Many articles including here, have shown me how to make C++/CLI delegates for use as C++ callback:
typedef void(*SDKUnManagedCB)(void * c, void *c2);
LATER...
[UnmanagedFunctionPointer(CallingConvention::Cdecl)]
delegate void sdkCBStyle(void * c, void *c2);
LATER...
sdkCBStyle^ users = gcnew sdkCBStyle(this, &SDK::UsersCB); //2nd parameter is method here in CLI file
IntPtr pUsers = Marshal::GetFunctionPointerForDelegate(users);
GC::KeepAlive(users); //freed later
GetUsers(static_cast<SDKUnManagedCB>(pUsers.ToPointer())); //GetUsers is unmanaged 3rd party API
My question is, I have about 20 callbacks with the same signature and I'd like to simplify the complicated CLI code. I'd like to do something like this:
GetUsers(CreateCallBack(&SDK::UsersCB));
GetActions(CreateCallBack(&SDK::ActionsCB));
//etc
Problem is I can't find the proper function signature for passing that function name. F12 (Go to Definition) goes to definition of delegate Intellisense also shows that function signature
MSDN has two protected constructors both take a String as the second parameter I tried to use
Delegate(Object, String)
But when I try:
SDKUnManagedCB CBCreator(String method) {
sdkCBStyle^ piCB = gcnew sdkCBStyle(this, method); // yes my variable names suck...
Real time compile has shows an error tooltip:
Error: invalid delegate initializer -- must be a function
I tried to look into CreateDelegate but this looks really slow
SDKUnManagedCB CBCreator(String^ method) {
MethodInfo^ info = GetType()->GetMethod(method, BindingFlags::Public | BindingFlags::Instance);
sdkCBStyle^ piCB = static_cast<sdkCBStyle^>(Delegate::CreateDelegate(sdkCBStyle::typeid, info));
GC::KeepAlive(piCB); // Yes this is a known leak, it will have to be stored as a member and explictly freed
return static_cast<SDKUnManagedCB>((Marshal::GetFunctionPointerForDelegate(piCB)).ToPointer());
}
Called with:
GetObjects(CBCreator("ObjectCB"));
Looks like it compiles, but is there an easier way?
EDIT: It crashes at runtime, An unhandled exception of type 'System.ArgumentException' occurred in mscorlib.dll Additional information: Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.
Do i need more binding parameters; the callback has to be a member function for data encapsulation