C and C++ get the core library itself rather than a binding. Every other language on this site is a thin layer over the same licdongle.h ABI, so you are working with the tested primary implementation, not a translation of it.
Linking
Static or shared, both are built. The library is C99 with hidden symbol visibility and explicit exports, so it drops into an existing build without polluting your namespace.
#include <licdongle.h>
licd_device *dev = NULL;
if (licd_open(ctx, NULL, &dev) != LICD_OK) return 1; /* first dongle */
if (licd_verify_genuine(dev) != LICD_OK) { licd_close(dev); return 1; }
licd_session_open(dev);
unsigned char buf[256];
size_t len = sizeof buf;
licd_record_read(dev, "license", buf, &len);
licd_close(dev);Code language: Arduino (arduino)
Two-call buffer convention
Anything that returns variable-length data follows one rule: call it with a capacity of zero to learn the size it needs, then call it again with a buffer. A zero-length record is a success with a length of zero, not an error — worth knowing before you write the error handling.
C++
The SDK ships an RAII wrapper: construction opens, destruction closes, errors become exceptions if you want them to. Nothing in it is required — it is a header over the same C API, so mixing the two is fine.
Where to put the check
Native code is the hardest target on this site, but a single if (genuine) is still a single conditional jump, and the people who do this for a living find those quickly. Use licd_app_decrypt on data your program genuinely needs, so that patching the check produces a program with nothing to compute rather than a working unlicensed copy.