Using C++ function pointers in C#

B

Bart Simpson

I have written a library in ('native') C++, and I have made a lot of use
of function pointers e.g.:

/* Example C++ callbacks:

typedef void (*CBFUNC1)(unsigned int, const char*, object&);
typedef object* (*CBFUNC2)(object*, struct _mystruct* );

*/

How may I call back into C# code? - ideally, I would like the callbacks
to 'raise events' (so that more than one event sinks may 'get in on the
act') but failing that, simply executing code on the C# side will suffice.
 
N

Nicholas Paldino [.NET/C# MVP]

Bart,

You can define a delegate in .NET, and then pass that to your unmanaged
code. The CLR will expose the delegate as a function pointer which you can
call from your unmanaged code.

You have a slight problem with your callback. The interop layer does
not know how to handle references in C++. You need to expose the object as
a pointer, not a reference. Additionally, .NET doesn't know what a C++
object is (it's not the same as System.Object). That will need to be passed
as an IntPtr, and I don't think there is much you can do with it in .NET.
The same thing goes for the second callback, you would have to return an
IntPtr, and it seems you are expecting something off the unmanaged heap (an
object allocated with new in C++, it would seem).

Your signatures for the delegates would be:

delegate void CbFunc1(uint param1, [MarshalAs(UnmanagedType.LPStr)] string
param2, IntPtr param3);
delegate IntPtr CbFunc2(IntPtr param1, ref _mystruct param2);

Hope this helps.
 
B

Bart Simpson

Nicholas said:
Bart,

You can define a delegate in .NET, and then pass that to your unmanaged
code. The CLR will expose the delegate as a function pointer which you can
call from your unmanaged code.

You have a slight problem with your callback. The interop layer does
not know how to handle references in C++. You need to expose the object as
a pointer, not a reference. Additionally, .NET doesn't know what a C++
object is (it's not the same as System.Object). That will need to be passed
as an IntPtr, and I don't think there is much you can do with it in .NET.
The same thing goes for the second callback, you would have to return an
IntPtr, and it seems you are expecting something off the unmanaged heap (an
object allocated with new in C++, it would seem).

Your signatures for the delegates would be:

delegate void CbFunc1(uint param1, [MarshalAs(UnmanagedType.LPStr)] string
param2, IntPtr param3);
delegate IntPtr CbFunc2(IntPtr param1, ref _mystruct param2);

Hope this helps.

Thanks. I notice you are passing the pointer toa struct as a ref
(instead of a IntPtr) in the 2nd delegate. Why is that (i.e. why not use
an IntPtr?)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top