Question

I am having difficulty using a thirdparty library registration function to register a callback. I am writing in C++ CLI, and accessing a library written in C or C++.

What does the above compiler error mean?

this is the registration function as defined by the vendor:

MYCO int WINAPI MyCo_Device_Register_CallbackFunc(LPVOID func, LPVOID lpParam, DWORD mask);

this is the callback as defined by the vendor:

typedef void (CALLBACK* MyCo_Device_CallbackProc)(DWORD ddStatus, LPVOID lpParam);

My callback function:

public ref class Device 
{
    void CallBackFunc(DWORD ddStatus, LPVOID lpParam) {};
}

My call (which fails):

MyCo_Device_Register_CallbackFunc((LPVOID) Device::CallBackFunc, nullptr, 0xFFFF);
Was it helpful?

Solution

If I had to wager a guess, you're trying to taken the address of a MANAGED function and pass it as a NATIVE function pointer. That won't work at all. Either write a native bridge (harder and probably no advantage), or (and this is the easier approach), create a delegate and use Marshal.GetFunctionPointerForDelegate. Don't forget that the delegate has to stay alive for the duration that the native code expects to call back, so you most likely need to store it somewhere.

Oh, and all functions inside a ref class or value class are managed functions, in case that wasn't clear.

[EDIT] Expanding answer to cover questions in comments. The first step is to create a matching delegate. For the function you provided, it's going to look like this:

public delegate void CallbackFuncDelegate(DWORD ddStatus, LPVOID lpParam);

Then, you'll need to create one:

CallbackFuncDelegate del = gcnew CallbackFuncDelegate(CallbackFunc);

And as noted previously, you should store that IN your class as a member in order to make sure it doesn't vanish. Lastly, you need to get the function pointer and pass it down:

MyCo_Device_Register_CallbackFunc((MyCo_Device_CallbackProc) Marshal::GetFunctionPointerForDelegate(del).ToPointer(), 0, 0);

I think that covers everything. All you need is using namespace System; and you should be fine.

OTHER TIPS

your callback func is a member -- pointer to members and pointers to functions are different things.

Even in Promit's solution:

CallbackFuncDelegate(CallbackFunc)

CallbackFunc should not be class member

You can write simply

public ref class Device 
{
    static void CallBackFunc(DWORD ddStatus, LPVOID lpParam) {};
}

and then use

Device::CallBackFunc
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top