2

I've seen the possible duplicate but the semantics are slightly different so I havent' been able to get it working until now. I'm not even sure it is really comparable to the pure c-function pointer style, which I've already used in different projects.

I have a DLL which defines a native C++ callback like this:

class NativeClass { // Native Callback Handler class, internal definition class Callback { public: // Constructor Callback() {} // Destructor virtual ~Callback() {} // Callback functions virtual void Handler() {} }; SetCallback(Callback* p) { ... } ... 

The DLL then consumes and fires the Callback by this function:

SetCallBack(NativeClass::Callback* p); 

So when I'm writing my C++/CLI wrapper, how can I pass a reference to a managed object exposing such a callback handler.

Is something like this generally not possible or how would I have to handle that correctly ? I've tried the following now according to the MSDN documentation and other SO answers:

typedef (__stdcall *NATIVE_CALLBACK)(void); public delegate void ManagedCallback(); ... public ref class Wrapper { public: Callback* _CBHandlerNative; NativeClass* nc; Wrapper() { _CBHandlerNative = new NativeClass::Callback(); _nc = new NativeClass(); // try assigning function pointer, but fails IntPtr ip = Marshal::GetFunctionPointerForDelegate(gcnew ManagedCallback(this, &Wrapper::ToBeCalled)); _CBHandlerNative->Handler = static_cast<NATIVE_CALLBACK>(ip.ToPointer()); _nc->SetCallback(_CBHandlerNative); } // managed handler void ToBeCalled() { ... } 
2
  • There is a page about this in MSDN documentation Commented Jun 18, 2014 at 10:54
  • @Jairo: looks promising, but does it also works for callback objects? I only see a callback Function, not an object with several functions. Or do I simply assign the Pointer to my wrapper function for each virtual function in the callback object ? Commented Jun 18, 2014 at 10:59

1 Answer 1

1

I have now a solution, which seems to be working correctly:

First, I'm defining a native proxy class for holding the callbacks:

public class CbProxy : Callback { public: NATIVE_CALLBACK _cbHandler; virtual void Handler() { if(_cbHandler != NULL) _cbHandler(); } } 

Now I can attach the managed delegate to the Handler proxy and pass it to the native DLL.

public delegate void ManagedCallback (); ManagedCallback^ mcb = gcnew ManagedCallback (this, &Wrapper::ToBeCalled); IntPtr ip = Marshal::GetFunctionPointerForDelegate(mcb); _pCbProxy->_cbHandler = static_cast<NATIVE_CALLBACK>(ip.ToPointer()); // ensure to keep a reference to the callback, otherwise it // will be freed GC::KeepAlive(mcb); GC::KeepAlive(ip); _nc->SetCallback(_pCbProxy); 

I'm not sure whether there is a more efficient way, but this works at first sight for me right now.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.