I have this code in C++
class MyClass { ... };
typedef MyClass (*Callback)();
Callback theCB;
static void RegisterCallback( Callback cb ) { theCB = cb; };
static void CallCallback() {
MyClass obj = theCB();
}
I am using swig but for simplicity (if you don't know swig) I have this wrapper in C#
public class MyClassWrapper
{
public IntPtr ptrToNativeObj; // pointer to native MyClass object
public MyClassWrapper()
{
ptrToNativeObj = call to native code that creates
and returns a new instance of MyClass in C++
}
};
Now I want to support the callback mechanism in C# so I set it up like this:
public MyClassWrapper MyFunction()
{
return new MyClassWrapper();
}
delegate MyClassWrapper CallbackDotNet();
static void main()
{
var fct = new CallbackDotNet( MyFunction );
P/Invoke call to native function RegisterCallback( fct );
then finally:
P/Invoke call to native function CallCallback();
}
I have all this code setup to work properly. The native code in CallCallback will call MyFunction properly.
But now I need to handle the returned object properly...
MyFunction returns a C# reference while the callback in C++ is returning by value so this would not work for free:
static void CallCallback() {
MyClass obj = theCB();
}
How can I marshall the "reference" to a MyClassWrapper object, returned from MyFunction, so that C++ receives "by-value" a MyClass object ?
Should I go ahead and write a custom marshaller ?
http://msdn.microsoft.com/en-us/library/zk0a8dea(v=vs.90).aspx
Then use it like here
[return: MarshalAs(UnmanagedType.CustomMarshaler,
MarshalType = "MyCustomMarshaler")]
delegate MyClassWrapper CallbackDotNet();
I looked at the documentation for custom marshallers and it's quite complex. Looks like the interesting method to implement is the following:
IntPtr MarshalManagedToNative( Object ManagedObj );
And the code will be something like
IntPtr MarshalManagedToNative( Object ManagedObj )
{
MyClassWrapper val = ManagedObj as MyClassWrapper;
return val.ptrToNativeObj;
}
But this will return a MyClass* back to the native code, not a MyClass value that this C++ code expects !
static void CallCallback() {
MyClass obj = theCB();
}
Will the marshaller be smart enough to dereference the pointer ?