mediapipe icon indicating copy to clipboard operation
mediapipe copied to clipboard

User data pointer in C API callbacks

Open chnoblouch opened this issue 1 year ago • 0 comments

The new tasks C API allows the user to process data asynchronously by setting a result callback in the task options. Here's the callback for the hand landmarker as an example:

// The options for configuring a MediaPipe hand landmarker task.
struct HandLandmarkerOptions {
  ...
  
  typedef void (*result_callback_fn)(HandLandmarkerResult* result,
                                     const MpImage& image,
                                     int64_t timestamp_ms,
                                     char* error_msg);
  result_callback_fn result_callback;
};

The issue I'm having now is that when this function is called, I can't use the results because I have no way of accessing my application data. The only workaround I can think of is creating a global variable for the application data, but I'd like to avoid global state in my code.

This is why C APIs usually implement callbacks using a function pointer along with a user-provided context pointer. The context pointer is passed to the callback function together with the results. Here's an example from the WebGPU C API (The context pointer is called userdata here):

typedef void (*WGPUBufferMapAsyncCallback)(WGPUBufferMapAsyncStatus status, WGPU_NULLABLE void * userdata) WGPU_FUNCTION_ATTRIBUTE;

...

WGPU_EXPORT void wgpuBufferMapAsync(WGPUBuffer buffer, WGPUMapModeFlags mode, size_t offset, size_t size, WGPUBufferMapAsyncCallback callback, WGPU_NULLABLE void * userdata) WGPU_FUNCTION_ATTRIBUTE;

I think adding a similar user data pointer to the C API would make it much more useful:

struct HandLandmarkerOptions {
  ...
  
  typedef void (*result_callback_fn)(HandLandmarkerResult* result,
                                     const MpImage& image,
                                     int64_t timestamp_ms,
+                                    void *user_data,
                                     char* error_msg);
  result_callback_fn result_callback;
};

...

MP_EXPORT int hand_landmarker_detect_async(void* landmarker,
                                           const MpImage& image,
                                           int64_t timestamp_ms,
+                                          void *user_data,
                                           char** error_msg);

chnoblouch avatar Feb 02 '24 15:02 chnoblouch