Show / Hide Table of Contents

# Wrapper for Usage in C/C++

## Overview

For Windows applications that are not .NET based, it may be possible to use `NixUniversalSDK` indirectly. For example, the SDK download provides a project `NixUniversalSDK.Wrapper` which allows for its usage in C/C++ applications.

The `NixUniversalSDK.Wrapper` contains single `IDeviceScanner` and `IDeviceCompat` instances. It provides a static interface to access these instances and also provides callbacks for device and scanner events. The project contains a basic implementation, but can be modified or expanded to better suit your specific application.

The wrapper project is part of the SDK examples which are available online.

### Known limitations

- The wrapper project is written in C# and is built to a self-contained native library using NativeAOT. NativeAOT builds use code-trimming and should specify runtime directives as described here. Note that the provided wrapper project has already declared these runtime directives; no further configuration is necessary.
- If an import `.lib` library file is required for linking in C/C++ applications, this import library file will need to be manually generated (see Generating an import library).
- As of February 2025, the wrapper project only supports x64, x86, and ARM64 builds
  - When using x86 builds, the calling convention is `cdecl`
  - The architecture limitations discussed here apply when using the wrapper. 32-bit (x86) builds do not support Bluetooth functionality when running on 64-bit (x64) architecture.

## Building the wrapper project

It is recommended to build the wrapper from the command line using `dotnet publish`.

1. Navigate to the `NixUniversalSDK.Wrapper` folder
2. Run the `dotnet publish -r <ARCH> -c Release` command for the desired architecture(s). Valid options for `<ARCH>` include
   - `win-x64`
   - `win-x86`
   - `win-arm64`

For example, to build for `win-x64`:

    dotnet publish -r win-x64 -c Release

3. The published files will be available under `bin/Release/net9.0-windows10.0.22621.0/<ARCH>/publish`

## Using the wrapper in a C/C++ project

After building the project, the output folder will also contain `NixUniversalSDK.Wrapper.h`. This C/C++ header file contains macros and function declarations for the exported functions available in `NixUniversalSDK.Wrapper.dll`. This file can be can be included in your C/C++ code to provide function declarations for the wrapper functions.

##### Tip

The API reference for the exported functions is available online.

### Generating an import library

In some cases an import `.lib` file is necessary for linking against the wrapper assembly. It is possible to manually generate this file using the `dumpbin` and `lib` utilities provided with Visual Studio.

#### Create an exports file

1. Open a Developer Command Prompt for VS2022.
   - For x64 builds, use x64 Native Tools command prompt.
   - For x86 builds, use x86 Native Tools command prompt.
   - For ARM64 builds, use the ARM64 Native Tools command prompt.
2. Use the `dumpbin` tool to generate a list of exported symbols in the `NixUniversalSDK.Wrapper.dll` assembly

    dumpbin /EXPORTS <PATH_TO_DLL>

3. Create a new text file `NixUniversalSDK.Wrapper.exports` and add the text `EXPORTS` to the first line.
4. Copy and paste the list of function names that were printed from the `dumpbin` tool. Keep only the function names.
   - The contents of the resulting `exports` file should be similar to the block shown below.
   - For convenience, you can copy and paste the block below verbatim, provided that you have not modified the exported functions in `Exported.cs` in the wrapper project.

    EXPORTS
    Device_Connect
    Device_Disconnect
    Device_GetBatteryLevel
    Device_GetExtPowerState
    Device_GetFieldCalibrationDue
    Device_GetFieldCalibrationEnabled
    Device_GetFieldCalibrationMaxDelta
    Device_GetFirmwareVersion
    Device_GetHapticFeedbackEnabled
    Device_GetHardwareVersion
    Device_GetId
    Device_GetInterfaceType
    Device_GetLastCalibrationDebug
    Device_GetLastCalibrationStatus
    Device_GetName
    Device_GetNote
    Device_GetPowerState
    Device_GetProvidesDensity
    Device_GetProvidesSpectral
    Device_GetReferenceJavaTicks
    Device_GetReferenceTemperature
    Device_GetRgbFeedbackEnabled
    Device_GetScanCount
    Device_GetScanTemperature
    Device_GetSerialNumber
    Device_GetSoftwareVersion
    Device_GetState
    Device_GetSupportedModes
    Device_GetSupportedReferences
    Device_GetSupportsFieldCalibration
    Device_GetSupportsHapticFeedback
    Device_GetSupportsRgbFeedback
    Device_GetSupportsTemperatureCompensation
    Device_GetTemperatureCompensationEnabled
    Device_GetType
    Device_HasOptions
    Device_InvalidateFieldCalibration
    Device_IsModeSupported
    Device_IsTileStringValid
    Device_LedTest
    Device_Measure
    Device_ProvidesColor
    Device_RegisterBatteryStateChanged
    Device_RegisterCommandCompleted
    Device_RegisterConnected
    Device_RegisterDisconnected
    Device_RegisterExtPowerStateChanged
    Device_RunFieldCalibration
    Device_SetFieldCalibrationEnabled
    Device_SetFieldCalibrationMaxDelta
    Device_SetHapticFeedbackEnabled
    Device_SetRgbFeedbackEnabled
    Device_SetTemperatureCompensationEnabled
    GetSdkId
    License_Activate
    License_Deactivate
    License_GetAllocations
    License_GetAllowedDeviceTypes
    License_GetExpiryJavaTicks
    License_GetFeatures
    License_GetLibraryVersion
    License_GetLibraryWrapperVersion
    License_GetState
    License_GetUuid
    License_IsDeviceTypeSupported
    License_IsFeatureEnabled
    Measurement_GetLastColorJson
    Measurement_GetLastDensityJson
    Measurement_GetLastHexCode
    Measurement_GetLastJavaTicks
    Measurement_GetLastMetadataJson
    Measurement_GetLastModesJson
    Measurement_GetLastSpectralJson
    Measurement_GetLastStatus
    Scanner_GetSortedResults
    Scanner_GetState
    Scanner_HasFoundDevice
    Scanner_ListUsbDevices
    Scanner_RegisterCreated
    Scanner_RegisterScanResult
    Scanner_RegisterStarted
    Scanner_RegisterStopped
    Scanner_Reset
    Scanner_SearchForId
    Scanner_Start
    Scanner_Stop

#### Create an import library file

1. Open a Developer Command Prompt for VS2022.
   - For x64 builds, use x64 Native Tools command prompt.
   - For x86 builds, use x86 Native Tools command prompt.
   - For ARM64 builds, use the ARM64 Native Tools command prompt.
2. Using the `lib` tool and the `NixUniversalSDK.Wrapper.exports` file from the previous step, generate an import library file.

For an x64 build:

    lib /def:NixUniversalSDK.Wrapper.exports /machine:x64 /out:NixUniversalSDK.Wrapper.lib

For an x86 build:

    lib /def:NixUniversalSDK.Wrapper.exports /machine:x86 /out:NixUniversalSDK.Wrapper.lib

For an ARM64 build:

    lib /def:NixUniversalSDK.Wrapper.exports /machine:ARM64 /out:NixUniversalSDK.Wrapper.lib

3. An import library `NixUniversalSDK.Wrapper.lib` will be generated in the current folder. This file can be used to link against the `NixUniversalSDK.Wrapper.dll` assembly

### Example C code

The wrapper project includes `example.c` located in the `example-c` folder. This example file demonstrates the usage of the NixUniversalSDK wrapper in a C application.

## Next steps

- Get additional support