C API Examples
The C API (Reader_C.h) provides an ABI-stable interface using opaque handles and RikResult error reporting. Every function takes RikResult& as its first parameter -- check HasException after each call.
The C API uses extern "C" linkage for ABI stability but is typically consumed from C++ source files. The examples below use C++ syntax for namespace-qualified types (e.g. RikCommon::ReaderDefinition).
Open, Init, Metadata, Beep, Close
#include <stdio.h>
#include "Reader/Reader_C.h"
int main() {
RikResult result = {0};
// Define reader
RikCommon::ReaderDefinition readerDef = {0};
readerDef.DeviceId.VendorId = 0x0C27;
readerDef.DeviceId.ProductId = 0x3BFA;
readerDef.ProtocolType = PROTOCOL_TYPE_FEATURE_REPORT;
// Open
ReaderPtr handle = RikReader_Open(result, readerDef, 3);
if (result.HasException) {
fprintf(stderr, "Open failed: %s\n", result.Message);
return 1;
}
// Init
Rik_Init(result, handle);
if (result.HasException) {
fprintf(stderr, "Init failed: %s\n", result.Message);
Rik_Close(result, handle);
return 1;
}
// Get metadata
ReaderMetadataStruct metadata = {0};
Rik_GetMetadataStruct(result, handle, &metadata, false);
if (!result.HasException) {
printf("Part Number: %s\n", metadata.PartNumber);
printf("Serial: %s\n", metadata.ESN);
}
// Beep
RikReader_Beep(result, handle, 2, BEEP_DURATION_SHORT);
if (!result.HasException) {
printf("Beeped!\n");
}
// Close
Rik_Close(result, handle);
return 0;
}
Get Card Data
void poll_card(ReaderPtr handle) {
RikResult result = {0};
uint8_t cardBuffer[64] = {0};
uint32_t bitCount = 0;
RikReader_GetCardData(result, handle, cardBuffer, sizeof(cardBuffer), bitCount);
if (result.HasException) {
fprintf(stderr, "Card read error: %s\n", result.Message);
return;
}
if (bitCount == 0) {
printf("No card present\n");
return;
}
printf("Card data (%u bits):", bitCount);
size_t byteCount = (bitCount + 7) / 8;
for (size_t i = 0; i < byteCount; i++) {
printf(" %02X", cardBuffer[i]);
}
printf("\n");
}
A bitCount of 0 means no card is present on the reader. Poll periodically to detect card presentation.
Get Library Info
No handle required -- call this at any time.
#include <stdio.h>
#include "Reader/Reader_C.h"
int main() {
LibraryInfo info = BuildLibraryInfo();
printf("RIK Version: %s\n", info.VersionString);
return 0;
}
Error Handling Pattern
The RikResult struct carries full error context. Use a goto-cleanup pattern for reliable resource release:
The goto-cleanup pattern ensures Rik_Close is always called, even when intermediate operations fail.
int configure_reader(const RikCommon::ReaderDefinition* readerDef) {
RikResult result = {0};
int rc = 0;
ReaderPtr handle = RikReader_Open(result, *readerDef, 3);
if (result.HasException) { rc = 1; goto done; }
Rik_Init(result, handle);
if (result.HasException) { rc = 1; goto cleanup; }
// Disable keystroking
RikReader_EnableKeystroking(result, handle, false);
if (result.HasException) { rc = 1; goto cleanup; }
// Set beeper volume
RikReader_SetBeeperVolume(result, handle, BEEP_VOLUME_HIGH);
if (result.HasException) { rc = 1; goto cleanup; }
printf("Reader configured successfully\n");
cleanup:
{
RikResult closeResult = {0};
Rik_Close(closeResult, handle);
}
done:
if (rc != 0) {
fprintf(stderr, "Error: %s\n", result.Message);
fprintf(stderr, " at %s:%d in %s\n",
result.FileName, result.LineNumber, result.FunctionName);
if (result.HasProtocolException) {
fprintf(stderr, "Protocol error: %s\n", result.ProtocolMessage);
}
}
return rc;
}
RikResult Fields
typedef struct {
bool HasException;
char ExceptionType[256];
char Message[2048];
char FileName[2048];
int LineNumber;
char FunctionName[256];
bool HasProtocolException;
char ProtocolExceptionType[256];
char ProtocolMessage[2048];
char ProtocolFileName[2048];
int ProtocolLineNumber;
char ProtocolFunctionName[256];
} RikResult;
| Field | Description |
|---|---|
HasException | true if the call failed |
Message | Human-readable error description |
FileName | Source file where the error originated |
LineNumber | Line number of the error |
FunctionName | Function that raised the error |
HasProtocolException | true if a protocol-level error also occurred |
ProtocolMessage | Protocol error description |