ContactGlove C++/C/Rust SDK V2
ContactGlove C++/C/Rust SDK V2 provides native libraries for C++, C, and Rust. It provides the C++ API, the stable C ABI v2 that is directly usable from C, and the official Rust bindings.
Distribution contents
bin/
contactglove-basic-usage(.exe)
contactglove-c-basic-usage(.exe)
ContactGloveSDKv2.dll / ContactGloveSDKv2d.dll (Windows; d is for Debug builds)
include/
contactglove/ContactGloveSDKv2.hpp
contactglove/ContactGloveSDKv2C.h
lib/
libContactGloveSDKv2.so / libContactGloveSDKv2.dylib / ContactGloveSDKv2.lib / ContactGloveSDKv2d.lib
cmake/ContactGloveSDKv2/
rust/
Cargo.toml
contactglove-sdk-v2/
contactglove-sdk-v2-sys/
share/
ContactGloveSDKv2/examples/
doc/ContactGloveSDKv2/Read the API reference online.
Installation
Windows (ZIP)
Extract the ZIP and use the extracted directory as the SDK root.
Expand-Archive .\ContactGloveSDKv2Cpp-<version>-Windows-AMD64.zip -DestinationPath .Linux (TGZ)
Extract the TGZ and use the extracted directory as the SDK root.
tar -xzf ContactGloveSDKv2Cpp-<version>-Linux-x86_64.tar.gzmacOS (Universal TGZ)
This TGZ supports Apple Silicon and Intel Macs running macOS 13 or later. Extract it and use the extracted directory as the SDK root.
tar -xzf ContactGloveSDKv2Cpp-<version>-macOS-universal.tar.gzUbuntu 22.04 / 24.04 (APT)
Install contactglove-sdk-v2 from the APT repository.
Supported systems are Ubuntu 22.04 (jammy) and 24.04 (noble) on amd64.
One-time setup
Obtain the public key contactglove-archive.asc from the distributor, then run these commands
in the directory where you saved it.
sudo apt-get update
sudo apt-get install ca-certificates gnupg
gpg --show-keys --with-fingerprint ./contactglove-archive.ascVerify that the primary key fingerprint matches:
DCBF 1BD7 8F31 3033 7506 DDF6 CC4A 11F6 725F 5132Register the verified key in a keyring used only for the SDK's APT repository.
sudo install -d -m 0755 /etc/apt/keyrings
gpg --dearmor --output contactglove-archive.gpg ./contactglove-archive.asc
sudo install -m 0644 contactglove-archive.gpg /etc/apt/keyrings/contactglove-archive.gpgUse the machine's codename when registering the APT repository. Confirm that VERSION_CODENAME
is jammy or noble, and that the architecture is amd64.
. /etc/os-release
echo "$VERSION_CODENAME"
dpkg --print-architecturecat <<EOF | sudo tee /etc/apt/sources.list.d/contactglove.sources > /dev/null
Types: deb
URIs: https://apt.melt-interface-technologies.com/ubuntu
Suites: ${VERSION_CODENAME}
Components: main
Architectures: amd64
Signed-By: /etc/apt/keyrings/contactglove-archive.gpg
EOFInstallation
sudo apt-get update
sudo apt-get install contactglove-sdk-v2After installation, the library, headers, CMake package configuration, and
contactglove-basic-usage are installed in their standard system locations.
Upgrade
You do not need to repeat the setup. To upgrade the installed SDK, run:
sudo apt-get update
sudo apt-get install --only-upgrade contactglove-sdk-v2Requirements
- ContactGlove3 Pro (with ContactGlove3, no data reaches the SDK)
- Windows 11 x64 (ZIP), Ubuntu 22.04 / 24.04 x86_64 (TGZ or matching DEB), or macOS 13+ (Universal TGZ for arm64 / x86_64)
- To build a C++ consumer: a C++17-capable compiler, such as GCC, Clang, or Visual Studio 2019 or later
- On Windows, the Microsoft Visual C++ Redistributable (x64)
- A running installation of DivingStation v2 or later
The prebuilt sample executables do not require a compiler. C consumers need a C compiler (the bundled C sample uses C11), and Rust consumers need Rust/Cargo 1.82 or later and the matching native SDK. The CMake consumer example below requires CMake 3.16+; building the SDK itself requires CMake 3.20+.
The SDK communicates with DivingStation over OSC. By default, DivingStation receives on port
25791 and the SDK receives on port 25788.
Connect from another PC
- Use a trusted LAN.
- In DivingStation's
SDK / Protocol, setListening scopetoExpose on LAN. If you change the listening scope, restart DivingStation. - Set the SDK's destination to the numeric IP address of the DivingStation PC and its listening port (default
25791). See the table below for each language's fields. - If the connection policy requires approval, allow the connection request shown in DivingStation.
- Allow the required UDP traffic on the actual receive ports of both PCs. The SDK receive port defaults to
25788.
| Language / connection settings | Numeric IP address of the DivingStation PC | DivingStation listening port | SDK receive port |
|---|---|---|---|
C++ Host | ipAddress | port | receivePort |
C cg_host_t | ip_address | port | receive_port |
Rust Host | ip_address | port | receive_port |
Verify the connection
- Start DivingStation.
- Connect and enable a ContactGlove3 Pro in DivingStation.
- Run the following command from the installed or extracted SDK.
Linux TGZ:
LD_LIBRARY_PATH="$PWD/lib" ./bin/contactglove-basic-usagemacOS Universal TGZ:
./bin/contactglove-basic-usageOn macOS, only the bundled contactglove-basic-usage and contactglove-c-basic-usage
executables have INSTALL_RPATH set to @loader_path/../lib. Configure library lookup
for your own application separately as described below.
Ubuntu DEB:
contactglove-basic-usageWindows ZIP:
.\bin\contactglove-basic-usage.exeOutput like the following confirms that the SDK is receiving data from DivingStation:
Listening on port 25788...
[callback] id=...
[poll] id=...[poll] waiting for callback data can appear immediately after startup.
contactglove-basic-usage automatically polls the glove ID first received by its callback.
Use from a CMake project
The ZIP/TGZ distributes prebuilt libraries and does not include the SDK source CMakeLists.txt. Build your
consumer project and reference the SDK with find_package() through CMAKE_PREFIX_PATH.
First, create a CMakeLists.txt for the consumer project.
cmake_minimum_required(VERSION 3.16)
project(my_app LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(ContactGloveSDKv2 CONFIG REQUIRED)
add_executable(my_app main.cpp)
target_link_libraries(my_app PRIVATE ContactGloveSDKv2::ContactGloveSDKv2)Then configure and build from the consumer project's directory. The -S . below refers to the
consumer project, not to the extracted SDK directory.
For a Linux DEB installation, no additional path is normally needed.
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build buildFor an extracted Windows ZIP:
cmake -S . -B build -DCMAKE_PREFIX_PATH="C:\path\to\ContactGloveSDKv2Cpp-<version>-Windows-AMD64"
cmake --build build --config ReleaseFor an extracted Linux TGZ:
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH="/path/to/ContactGloveSDKv2Cpp-<version>-Linux-x86_64"
cmake --build buildFor an extracted macOS Universal TGZ:
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH="/path/to/ContactGloveSDKv2Cpp-<version>-macOS-universal"
cmake --build buildOn Windows, your application must be able to find ContactGloveSDKv2.dll at runtime. The simplest approach is to copy
bin/ContactGloveSDKv2.dll beside your application's .exe. Alternatively, add the SDK distribution's
bin/ directory to PATH. For a Linux DEB installation, libContactGloveSDKv2.so is installed in
the standard multiarch library path.
The Windows ZIP also contains ContactGloveSDKv2d.dll for Debug builds. With find_package(), Debug
builds of your application select ContactGloveSDKv2d.dll, and Release, RelWithDebInfo, and MinSizeRel
builds select ContactGloveSDKv2.dll. The MSVC Debug and Release C++ runtimes are not compatible, so
when you copy the DLL manually, use the one that matches your application's build configuration.
For an app distributed on macOS, bundle libContactGloveSDKv2*.dylib in the app bundle and
configure an @rpath that resolves to that location. Distributing only a copied library is not
supported outside of the samples bundled in the TGZ.
You can automate the Windows DLL copy in the consumer project's CMakeLists.txt.
if(WIN32)
add_custom_command(TARGET my_app POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:ContactGloveSDKv2::ContactGloveSDKv2>
$<TARGET_FILE_DIR:my_app>
VERBATIM)
endif()C ABI and Rust bindings
include/contactglove/ContactGloveSDKv2C.h is the C/C++-compatible C ABI v2 header.
Use it from C with cg_sdk_* functions and link the same native SDK library. The bundled
share/ContactGloveSDKv2/examples/c_basic_usage.c shows connection, polling, and subscriptions.
In CMake, use project(my_c_app LANGUAGES C), add_executable(my_c_app main.c), and
target_link_libraries(my_c_app PRIVATE ContactGloveSDKv2::ContactGloveSDKv2) with the
same find_package() and runtime library setup as the C++ consumer.
See the API reference for buffer and callback lifetimes.
For Rust, use the bundled workspace. Open rust/ under the SDK root for a ZIP/TGZ, or
share/ContactGloveSDKv2/rust/ for a DEB installation, set the SDK root, then run Cargo.
$env:CONTACTGLOVE_SDK_ROOT = "C:\path\to\ContactGloveSDKv2Cpp-<version>-Windows-AMD64"
$env:PATH = "$env:CONTACTGLOVE_SDK_ROOT\bin;$env:PATH"
cargo run --manifest-path "$env:CONTACTGLOVE_SDK_ROOT\rust\Cargo.toml" -p contactglove-sdk-v2 --example basic_usageFor a macOS Universal TGZ:
export CONTACTGLOVE_SDK_ROOT="$PWD"
export DYLD_LIBRARY_PATH="$CONTACTGLOVE_SDK_ROOT/lib:${DYLD_LIBRARY_PATH:-}"
cargo run --manifest-path "$CONTACTGLOVE_SDK_ROOT/rust/Cargo.toml" -p contactglove-sdk-v2 --example basic_usageTo use the binding from your own Cargo project, add
contactglove-sdk-v2 = { path = "<SDK root>/rust/contactglove-sdk-v2" } to [dependencies] in Cargo.toml,
set the same environment variables as above, then run cargo run.
For a DEB installation, set path to /usr/share/ContactGloveSDKv2/rust/contactglove-sdk-v2; no environment variables are needed.
Sdk and Subscription are not Send or Sync. Callbacks run on the SDK receiver thread;
copy or send owned values to another thread when needed. Drop each Subscription before
disconnecting or dropping Sdk. Binding regeneration is a maintainer procedure in the
Rust README.
Minimal code example
#include <chrono>
#include <iostream>
#include <thread>
#include "contactglove/ContactGloveSDKv2.hpp"
int main() {
ContactGloveSDKv2::SDK sdk;
sdk.RegisterCallbackForGloveDataStream([](const ContactGloveSDKv2::GloveData& g) {
std::cout << "glove id=" << g.id
<< " battery=" << g.batteryPercentage << "%"
<< "\n";
});
ContactGloveSDKv2::Host host;
host.hostName = "localhost";
host.ipAddress = "127.0.0.1";
host.port = 25791;
host.receivePort = 25788;
if (sdk.ConnectToHost(host) != ContactGloveSDKv2::SDKReturnCode::Success) {
std::cerr << "Failed to start the connection (socket or port error)\n";
return 1;
}
std::this_thread::sleep_for(std::chrono::seconds(5));
sdk.Disconnect(host);
return 0;
}For a longer sample, see:
share/ContactGloveSDKv2/examples/basic_usage.cppTroubleshooting
contactglove-basic-usage continues to display [poll] waiting for callback data:
- Confirm that DivingStation is running.
- Confirm that the glove is connected in DivingStation.
- Confirm that no other application is using SDK receive port
25788.
[callback] id=... appears, but [poll] <id>: no data yet continues:
- Exit
contactglove-basic-usage, make sure no other application uses the same SDK receive port, then run it again. - Confirm that the glove is enabled in DivingStation.
ContactGloveSDKv2.dll cannot be found when the application starts:
- Copy
bin/ContactGloveSDKv2.dllbeside your.exe. - Or add the SDK distribution's
bin/directory toPATH.
A Windows Debug build exits inside ConnectToHost() (for example with exit code 3):
- The Debug application loaded the Release
ContactGloveSDKv2.dll. Use an SDK distribution that containsContactGloveSDKv2d.dll, and copy the DLL with$<TARGET_FILE:...>as shown above. - With an SDK that does not contain
ContactGloveSDKv2d.dll, build your application as Release or RelWithDebInfo.
libContactGloveSDKv2.so.0 cannot be found on Linux:
- Confirm that the DEB is installed.
- When using a TGZ extracted to a custom prefix, add its
lib/directory toLD_LIBRARY_PATH.
Library not loaded: @rpath/libContactGloveSDKv2...dylib appears on macOS:
- Run the bundled samples from the SDK root's
bin/directory. - For the Rust bindings or your own application, add the SDK root's
lib/directory toDYLD_LIBRARY_PATHor configure the application's@rpathcorrectly.
A Gatekeeper warning appears on macOS:
- This initial distribution is not signed or notarized. Verify its source and contents, then run it in accordance with your organization's macOS security policy.
The source directory ... does not appear to contain CMakeLists.txt:
- You passed the extracted SDK directory to
cmake -S. The ZIP/TGZ does not contain aCMakeLists.txt; pass the consumer project directory to-Sand specify the SDK directory only throughCMAKE_PREFIX_PATH.
find_package(ContactGloveSDKv2 CONFIG REQUIRED) fails:
- Specify the extracted SDK root in
CMAKE_PREFIX_PATH. - Or set
ContactGloveSDKv2_DIRto<SDK_ROOT>\lib\cmake\ContactGloveSDKv2.
Build the SDK from source
The prebuilt distribution and SDK source checkout serve different purposes. To build the SDK, use the source repository, CMake 3.20+, a C++17 compiler (MSVC 2019+, GCC 9+, or Clang 9+), and Git for the pinned oscpack dependency fetched by CMake. On macOS use Xcode Command Line Tools; the Universal package option targets macOS 13+ and both arm64 and x86_64.
git clone https://github.com/MeltInterfaceTechnologies/ContactGloveSDKv2Cpp.git
cd ContactGloveSDKv2Cpp
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --config ReleaseFor a macOS Universal build, add -DCONTACTGLOVE_MACOS_UNIVERSAL=ON at configure time.
See the source README for installation, packaging, and API generation maintenance commands.
License
The SDK's Melt Interface Technologies code, C/C++ headers, Rust bindings, samples, and SDK documentation are licensed under the Apache License, Version 2.0. The full license text is located at:
share/doc/ContactGloveSDKv2/LICENSE.mdCopyright attribution is in NOTICE.md in the same directory.
Third-party components retain their own licenses and are not relicensed under Apache-2.0. Third-party notices and licenses are at:
share/doc/ContactGloveSDKv2/THIRD_PARTY_NOTICES.mdoscpack is built into the SDK as an internal dependency and pinned to revision
3e7e3a102e316d75fe176885a6dd08f216f2eac0.
Separately maintained protocol specifications are not included in the SDK distribution. Retrieving them is not required to build or use the SDK.
Contact
For questions or bug reports about this SDK, use the contact form.