Given the following C library with a callback event that ask to set a buffer, how to write a proper C++/CLI wrapper in a type safe manner?
// The callback signature
typedef void (__cdecl *BUFFERALLOCATOR)(void *opaque, void **buffer);
// A struct that contains the context of the library
struct lib_context_base_s
{
// The stored callback function pointer
BUFFERALLOCATOR buffer_allocator;
// Opaque pointer that contain the local context. Needed in C because
// C doesn't have closures (functions that knows the context where
// they are defined)
void* opaque;
};
typedef struct lib_context_base_s lib_context_base;
// Init the base context
lib_context_base* new_lib_context_base()
{
return malloc(sizeof(lib_context_base));
}
// Free the base context
void free_lib_context_base(lib_context_base *lib_context_base)
{
free(lib_context_base);
}
// Set the buffer allocation callback
void set_allocate_buffer_callback(lib_context_base *lib_context_base,
BUFFERALLOCATOR allocate_buffer, void* opaque)
{
lib_context_base->buffer_allocator = allocate_buffer;
lib_context_base->opaque = opaque;
}
The library should be usable by managed code using the delegate void BufferAllocator(ref IntPtr buffer) .
I will insist on type-safe principles: I know there’s already
Marshal.GetFunctionPointerForDelegatebut that requires function pointer type cast in C++/CLI and hides how marshalling unmanaged->managed works (debugging is much harder and I don’t like not understanding what’s happening behing the scene). Just noticed the approach is similar to this but doesn’t need a managed native class (less overhead). Please, tell me if you know how to further simplify it (mantaining type safety and marshaling control) and reduce overhead.The following is the C++/CLI
Wrapper.hheader:Follows C++/CLi
Wrapper.cppdefines:Can be used in this way (C#):