Skip to main content
Wuji SDK ships a C API (libwuji_sdk_c.so + wuji_sdk.h) with the same semantics as the Python interface. For installation alongside Python, see Installation and Environment. This page covers the C-side initialization conventions, memory and callback constraints, error code decoding, and project build setup. Per-device C APIs live with each product’s docs: Wuji Hand 2 SDK Reference and Wuji Glove SDK and Data Reference. Cross-device capabilities live in the capability chapters, each with an operation / Python / C table: Device Discovery & Connection, SDK Users and Calibration Data, Data Subscription Mechanism, Time Synchronization and Coordinate Transforms, and Hand Retargeting. The complete typed callback signatures and struct definitions live in include/wuji_sdk.h of the extracted tarball (download it from wuji-sdk Releases). The CMake example and build instructions are in the examples/c/ directory of the wuji-sdk repo.

Initialization and conventions

Initialization Call once at process start and release at shutdown:
Return value taxonomy
  • WujiStatus — most operations (wuji_init / wuji_scan / wuji_connect / opening subscriptions, etc.). WUJI_STATUS_OK means success. On failure, retrieve the per-thread error string via wuji_last_error().
  • int32_t — metadata readers (wuji_dev_serial_number / wuji_dev_device_name) return the number of bytes written.
  • uint8_t — status query wuji_dev_is_connected.
  • void — wuji_shutdown and resource cleanup functions.
Resource cleanup functions
  • wuji_discovered_free — release the device list returned by wuji_scan
  • wuji_dev_release — paired with wuji_connect, release the device handle after disconnecting
  • wuji_sub_close — close the subscription handle
User Info Struct WujiUserInfo holds seven fields: user_id, display_name, description, external_id, is_default, created_at, and updated_at. wuji_update_user takes a WujiUserUpdate carrying only the fields to change, and setting clear_description / clear_external_id clears the matching value. For the full user management API list, see SDK Users and Calibration Data.

Error Code Description

wuji_hand_2_describe_error is a static function (no device connection needed) that decodes a device fault code (from joint_diagnostics’s error_code_current — the same values carried by the error history and calibration results in the Python SDK) into WujiErrorInfo. It accepts device fault codes only. Calibration in the Python SDK also reports a separate encoder-only error byte — that one is a different, unrelated enum and must not be passed in. The WujiHandJointDiagnostics.error_code bitfield from Wuji Hand joint diagnostics (returned by wuji_hand_get_all_diagnostics) must not be passed in either:
Unknown codes return WUJI_STATUS_ERR_NOT_FOUND. severity values: Warning / DeferredStop / ImmediateStop / Fatal. clear_policy values: AutoClear / ManualClear / NonClearable.

Usage constraints

C SDK users must observe the following constraints to avoid use-after-free, deadlocks, and reading stale error strings.
  • A typed callback’s frame pointer is valid only for the duration of the callback. Heap fields are released after the callback returns. Copy whatever you need to retain inside the callback. Do not store the pointer.
  • Never call wuji_sub_close from inside that subscription’s own callback. close joins the worker thread and will deadlock if called from the callback itself. Close from a different thread.
  • The return value of wuji_last_error() is only valid until the next wuji_* call on the same thread. Copy the message immediately if you need to retain it.
  • END and ERROR are terminal frames — no further data will arrive after them, but you still need to call wuji_sub_close to release the subscription handle.
  • String getters use a two-call query: first call with buf=NULL, buf_len=0 to read *needed (required bytes including NUL), then allocate and call again to fill. Passing an undersized buffer returns WUJI_STATUS_ERR_BUFFER_TOO_SMALL and never truncates.
  • Whole-hand batch reads (get_all_effort_limit / get_all_mit_params) return a flat-20 array plus an online bitmap. Use the WUJI_JOINT_ONLINE(mask, i) macro to check slot validity, otherwise you will read offline-joint placeholders (0 or NaN).
  • The calibration feedback callback runs on the calibration worker thread, and the feedback pointer is valid only during the callback. The SDK guards the session calls made from inside it rather than deadlocking: wuji_glove_calibration_wait and wuji_glove_calibration_try_finish return WUJI_STATUS_ERR_INVALID_ARG, and wuji_glove_calibration_session_free records the reason in wuji_last_error() and skips the release — so the session stays alive and you must free it again after the callback returns. wuji_glove_calibration_cancel is safe to call from the callback. Free the session with wuji_glove_calibration_session_free and the result with wuji_glove_calibration_result_free.
  • WujiUserInfo holds heap strings: free a single struct with wuji_user_info_free, and free an array returned by wuji_list_users with wuji_user_info_array_free.

Python equivalents

The table below maps each C API to its Python counterpart by capability. For full usage of the cross-device capabilities, see the capability chapters listed at the top of this page. For per-device APIs, see the matching section on this page.
CapabilityCPython
Initwuji_init(NULL)SdkManager.instance()
Scanwuji_scan(&devs, &count)manager.scan()
Connectwuji_connect(&target, alias, &opts, &dev)manager.connect(…) / manager.auto_connect(…)
Default connect optionswuji_connect_options_default()ConnectOptions()
Device subscribewuji_glove_subscribe_tactile(dev, cb, user, &sub)glove.tactile().subscribe_with_callback(…)
Global subscribewuji_subscribe_tf(cb, user, &sub)manager.tf().subscribe()
Stream output ratewuji_sub_set_rate(sub, hz, &actual)sub.set_rate(hz)
Hand 2 control actionwuji_hand_2_enable(dev, mask)hand.enable(joints=mask)
Hand 2 realtime commandwuji_hand_2_joint_command_publish + wuji_joint_command_publisher_sendhand.joint_command().publish().send([…])
Hand 2 joint state subscribewuji_hand_2_subscribe_joint_stateshand.joint_states().subscribe()
Hand 2 joint diagnostics subscribewuji_hand_2_subscribe_joint_diagnosticshand.joint_diagnostics().subscribe()
Hand 2 IMU subscribewuji_hand_2_subscribe_imuhand.imu().subscribe()
Hand 2 error descriptionwuji_hand_2_describe_error(code, &info)WujiHand2.describe_error(code)
Hand 2 flash log exportwuji_hand_2_export_flash_logs + wuji_hand_2_flash_log_export_freehand.export_flash_logs()
Hand connect (USB SN)wuji_hand_connect_sn(sn, alias, &dev)WujiHand.connect_sn(sn, alias)
Hand joint state subscribewuji_hand_subscribe_joint_stateshand.joint_states().subscribe()
Hand realtime commandwuji_hand_joint_command_publish + wuji_hand_joint_command_publisher_sendhand.joint_command().publish().send([…])
Hand realtime controllerwuji_hand_realtime_controller_open / _set_target_position / get_actual*hand.realtime_controller(LowPass(…))
Glove time syncwuji_glove_sync_time(dev, &tsr)glove.sync_time()
Glove hand model pathwuji_glove_get_hand_model_path / wuji_glove_set_hand_model_pathglove.hand_model_path().get() / .set(path)
SDK user managementwuji_create_user / wuji_switch_user / wuji_list_usersmanager.create_user() / switch_user() / list_users()
User data export and importwuji_user_data_export / wuji_user_data_preview / wuji_user_data_importmanager.export_user_data() / preview_user_data() / import_user_data()
Glove hand model calibration (async)wuji_glove_calibration_start + wuji_glove_calibration_try_finishglove.calibrate()
Glove hand model calibration (sync)wuji_glove_calibrateglove.calibrate_blocking()
Glove tactile contact calibration (sync)wuji_glove_calibrate_tactile_blockingglove.calibrate_tactile_blocking()
Disconnectwuji_dev_disconnect + wuji_dev_releasedevice.disconnect()

CMake project example

A complete runnable C project (with CMakeLists.txt plus a subscription callback demo) lives in the examples/c/ directory of the wuji-sdk repo, organized into examples/c/wuji_glove/ (stream output rate control, custom hand model for online IK, SDK user management, and hand model calibration), examples/c/wuji_hand_2/ (joint-state subscriptions, control actions, device info, fingertip tactile data, stream output rate control, flash-log export, opposition replay, and MIT sweep), and examples/c/wuji_hand/ (subscriptions, publishing, grasp loops, and tactile status) subdirectories. See that directory’s README for build instructions. Minimal link:
${SDK} is the extracted tarball root. The CMake project uses -DWUJI_SDK_INCLUDE_DIR and -DWUJI_SDK_LIB to point at the same paths.