Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

two way communication between unmanaged code and unity3d code

Tags:

c++

mono

unity3d

I have two apps. One of them is written in visual c++ and the other is a unity app, both are running on windows. In my scenario, I want to call a unity function and draw an object whenever user presses on a button in my c++ app. So far, I have tried to load unity executable into the same address space with the c++ app by calling mono_domain_assembly_open. However, it always returns null and I am not able to call mono_jit_exec to run unity app. Is this possible to maintain two way communication between those two applications using mono? Thanks in advance!

like image 789
okante Avatar asked Aug 15 '13 21:08

okante


1 Answers

Here is an old example I have, based off of this post. What you want is to pass your C# delegate to C++ as a function pointer. You can store that function pointer for use by your button, or whatever else you'd like.

C++ DLL:

typedef int ( __stdcall *UnityCallback )( int );

static UnityCallback gCallBack;
extern "C" __declspec( dllexport )
inline int CallbackExample( UnityCallback unityFunctionPointer, int n )
{
    gCallBack = unityFunctionPointer;
    if( gCallBack )
    {
        return gCallBack( n );
    }
    return 0;
}

C# Caller:

using UnityEngine;
using System;
using System.Runtime.InteropServices;

public class Callback : MonoBehaviour {
    public delegate int CallbackDelegate( int n );

    [DllImport ("UnityPluginCallback")]
    private static extern int CallbackExample(CallbackDelegate fp, int n);

    void Awake()
    {
        int result = CallbackExample(new CallbackDelegate(this.CallbackTest), 42);
        Debug.Log("Result from callback, should be 43: " + result);
    }


    int CallbackTest( int n )
    {
        Debug.Log("Received: " + n + " from C++ dll");
        return n+1;
    }
}

In my example, the C++ DLL immediately calls the C# callback with a value of 42. C#'s callback increments this value by 1 and returns it to C++ which in turn returns it to C# at the CallbackExample call site.

Unity doesn't like it when you try to access the engine outside of the main thread so I'm not sure what happens if your C++ DLL has asynchronous calls back to C#. In my example the calls starts in the main unity thread so there aren't an issues. I would suggest you do not allow any Unity specific functionality in the C# callback, instead use the callback to set a boolean(or some other mechanism) to be used by Update to implement whatever it is you want from the Unity engine.

like image 162
Jerdak Avatar answered Oct 30 '22 23:10

Jerdak