meds
meds

Reputation: 22916

Calling C# code from unmanaged C++?

In Mono you can pass a delegate from C# to a C++ function which takes in the delegate as a function pointer. Can this be done in C# on Windows for example where you can compile a native C++ unmanaged library, link it against a C# project and get a C++ function to invoke a C# function via a function pointer which C# passed to it as a delegate?

Upvotes: 1

Views: 5625

Answers (5)

natbro
natbro

Reputation: 1038

Rohit's answer is right, but there are lots more gotcha's on the path depending on whether you're calling back immediately (C# calls C++ which calls back C#) or if you want to call back repeatedly (C# calls C++ and after returning calls back one or more times later to C#).

i wrote this example from the perspective of Unity/C# and C/C++/Objective-C interop, but you may find some of the comments and code-snippets useful no matter where you are doing C#/C interop.

in particular make sure that you're propertly retaining/holding any delegates you pass from C#/managed to C/unmanaged code if the C/unmanaged code might be calling back at a different time.

Upvotes: 1

David Heffernan
David Heffernan

Reputation: 612794

You are looking for Marshal.GetFunctionPointerForDelegate().

Upvotes: 1

Alexei Levenkov
Alexei Levenkov

Reputation: 100527

This obviously can be done - all CLR hosts are native applications to start with. Your options:

  • in managed application call your native DLL (PInvoke)
  • call managed COM object (as Dan suggested)
  • host CLR yourself - sample

Upvotes: 1

Rohit Vipin Mathews
Rohit Vipin Mathews

Reputation: 11787

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.

The interop layer does not know how to handle references in C++. So 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.

C++ callbacks:

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

C# 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);

Upvotes: 6

Dan
Dan

Reputation: 1959

One option you have is to use C++/CLI to call into the C# code. If your C++ code must stay unmanaged (native), then you should wrap your C# code in a COM component and use it from your C++ code.

Upvotes: 1

Related Questions