Communicating C# with C++

This isn’t exactly a Unity-specific question, but since I’m implementing this in Unity some people might have tried doing this.

I have a C++ plugin which has “observables”. I would like to register a callback from a C# function (from Unity) to my C++ observable class. Is it possible for my C++ code to call a C# callback? Any ideas how this could be done?

I know very little of C# and basically I found something related to “delegates”, but I don’t know how to use it and have no idea how it would integrate with C++.

Thanks in advance

2 Likes

It is technically possible but your C++ plugin must run in the engines thread, otherwise it will crash if the callback you try to call accesses anything from the unity engine. Unity is not thread safe and you must not access its “space” from another thread.

To create such a callback, just send the function out to the C++ layer for calling through marshaling, thats rather straight forward, for void return type no effort is required at all.

Create a C# delegate for the function you want to call, and use Marshal.GetFunctionPointerForDelegate. Docs: Marshal.GetFunctionPointerForDelegate Method (System.Runtime.InteropServices) | Microsoft Learn

Thanks a lot for the help guys…

Now I have another question

How would I define that using Unity C# DLLImport?

Obviously doesn’t work. I tried changing the function pointer (in the DLL and in C# script) from ANSWERCB to System::IntPtr, but I wasn’t able to compile the DLL this way (I even tried compiling with /clr, which I think makes the DLL stop working in Unity, but even with /clr it failed to compile).

Not sure how I can get this specific part to work now… any ideas?

Tried changing ANSWERCB to void*, but I don’t know how that would look like in C# either… Sorry, I really don’t know how to work with C# :frowning:

1 Like

http://www.mono-project.com/Interop_with_Native_Libraries

I was able to get it to work, thanks a lot guys.

In case anyone has the same doubt and is looking for an answer, here’s an example:

C++ DLL code (build as DLL, disable /clr [Common Language Runtime])

Unity C# Script using the DLL

10 Likes

Thanks for posting the code! Very helpful!

Two years later and I found it very helpful as well.

Thanks!

In the example script, can myCallback() be static? Thanks for the example code, it is very helpful.

So greate!!! I spent 2 days in this problem.

thank you - it’s insane that this was so difficult to track down.

for those of you that may run across this in the future in the context of Unity 3D, here is an example native-code plugin and test Unity project which demonstrate callbacks, recurring callbacks, and simple byte marshaling from native code back to Unity/C#. It’s pretty applicable to any kind of mono/C# integration, though.

2 Likes

I’ve tried this on Windows, having in mind that my dll calls unity from another thread. It works well as long as you’re only trying to update some data members of the C# class (like in my example: 2 ints). But if you’re trying to do something with the updated ints like reposition some object, it won’t work anymore and unity crashes. So it all works as espected.

The real deal would be: how do I call such a callback function from my dll inside the thread that registered the callback? Any ideas?

Hi guys, sorry to revive an old thread. I’m desperately trying to understand Delegates and Marshaling in order to be able to call a Unity function from a plugin. From what I can tell, Dam-Pete’s solution does the opposite; It looks like Unity is calling a function from the plugin.
Does anyone know how to get a plugin to call a C# unity function?

Thanks

Many years later and this helped me a lot!

Probably late, but for people in future: actually, Pete’s solution (post #6) works exactly like that. Or to be more precise: function TakesCallback is called from Unity to C/C++ plugin. But with this function you register a C# callback/delegate so in future, when you need to communicate from plugin to C#, you can use this delegate.

If would like to clarify one thing for people searching this problem in future: generally, when you call something on C/C++ side from C#, anything you pass will exist (is valid) only during the call, which would be pretty problematic for delegates. However delegates are an exception: function pointer passed to C/C++ from C# is valid as long as original C# delegate object exists. That means we should create a delegate variable for the C/C++ callback and keep it alive while C/C++ can invoke it! (Of course it’s not necessary if the callback can be invoked only during the C/C++ call.) Source: Interop with Native Libraries | Mono

2 Likes

Hi, Thanks for the code but some native libraries are using c structs containing multiple callbacks. How to use those in unity C#.
##real vnc sdk code
typedef struct {
void(requestUserCredentials)(void userData,
vnc_Viewer* viewer,
vnc_bool_t needUser,
vnc_bool_t needPasswd);

void
(cancelUserCredentialsRequest)(void userData,
vnc_Viewer* viewer);
} vnc_Viewer_AuthenticationCallback;

Here we have to register for callback in c
//For documentation visit https://www.realvnc.com/de/developer/docs/latest/api/c/
vnc_Viewer_setAuthenticationCallback(vnc_Viewer *viewer, const vnc_Viewer_AuthenticationCallback *callback, void *userData)

Sets the callback to be called when a username and/or password is required.