简体   繁体   English

用C ++实现Unity3D的Marshal C#方法

[英]Marshal C# Method to Unity3D with C++

I would like to call a specific method in my Unity3D project within an external plugin. 我想在外部插件中调用Unity3D项目中的特定方法。 Here is my C++ code: 这是我的C ++代码:

static void UNITY_INTERFACE_API OnRenderEventThreadSafe(int eventID)
{
    [...] Some C++ code
    //Call C# Method here
}

My C++ code does already work on its own but now I want to call a specific C# method. 我的C ++代码已经可以自己运行,但现在我想调用一个特定的C#方法。 How can I manage to do this? 我该如何设法做到这一点? I tried creating delegates like this 我尝试像这样创建委托

#if UNITY_EDITOR
[DllImport("lib")]
#else
[DllImport ("lib")]
#endif
private static extern void Method(Delegate callback);

private delegate void Delegate(int number);

[MonoPInvokeCallback(typeof(Delegate))]
private static void DelegateMessageReceived(int number)
{
    Debug.Log("MessageReceived " + number);
}

public static void Method2()
{
    Method(DelegateMessageReceived);
}

But I don't think this is the right way... Should have mentioned it earlier, but I'm coding on Linux-Fedora25 但我不认为这是正确的方法......本来应该提到它,但我在Linux-Fedora25上编码

I ran into the-same issue in the past when making rendering plugin but the solution is not really hard. 我在制作渲染插件时遇到了同样的问题,但解决方案并不是很难。

You need to create a global static function pointer to hold the C# function you want to call from C++. 您需要创建一个全局static 函数指针来保存要从C ++调用的C#函数。 The C++ function pointer must be static . C ++函数指针必须是static Initialize this variable from the Start or Awake function in C#. 从C#中的StartAwake函数初始化此变量。 After this, you can freely call that function anytime from C++. 在此之后,您可以随时从C ++中自由调用该函数。

C++ ( YourCppPlugin.h ) C ++YourCppPlugin.h

#define DLLExport __declspec(dllexport)

extern "C"
{
    //Create a function pointer and give it a callback alias to shorten it
    typedef void(*FuncCallBack)(int eventID);

    //Create a callback delegate from the alias to hold the function from C#
    static FuncCallBack callbackInstance = nullptr;

    //Create the function that will be called from C# to store the function
    DLLExport void RegisterRenderCallback(FuncCallBack cb);
}

C++ ( YourCppPlugin.cpp ): C ++YourCppPlugin.cpp ):

#include "YourCPP.h"

//Save the function we received from C# to the global variable for future use:

void RegisterRenderCallback(FuncCallBack cb) {
    callbackInstance = cb;
}

Done. 完成。 You can now use the callbackInstance variable to call the C# function anytime from the Unity's UNITY_INTERFACE_API OnRenderEventThreadSafe C++ API function. 您现在可以使用callbackInstance变量随时从Unity的UNITY_INTERFACE_API OnRenderEventThreadSafe C ++ API函数调用C#函数。 Just make sure it's not null before calling it like below: 在调用它之前确保它不是null ,如下所示:

static void UNITY_INTERFACE_API OnRenderEventThreadSafe(int eventID)
{
    [...] Some C++ code

    //Call C# Method here
     if (callbackInstance != nullptr)
        callbackInstance(eventID);
}

Register a function to it first from C# with the RegisterRenderCallback function first before using the callbackInstance variable. 在使用callbackInstance变量之前,首先使用RegisterRenderCallback函数首先从C#注册一个函数。 See example in the Start function below. 请参阅下面的Start功能中的示例。


C# side of the code: C#侧代码:

// Use this for initialization
void Start()
{
    //Register the OnRenderCallback function to our C++ plugin for a callback
    RegisterRenderCallback(OnRenderCallback);
}

//Function that registers a local C# function to a delegate in C# for later use
[DllImport("YourCppPlugin", CallingConvention = CallingConvention.Cdecl)]
static extern void RegisterRenderCallback(renderCallback cb);

//int param callback delegate that links to the C# function we want to call from C++
delegate void renderCallback(int eventID);

//Function we want to call from C#. Registered in the Start function
[MonoPInvokeCallback(typeof(renderCallback))]
static void OnRenderCallback(int eventID)
{
    Debug.Log("Called from C# with ID: " + eventID);
}

Finally, if you have more than one function to register, you have to use List, array or dictionary to hold them on both C# and C++ side then iterate and call each one when necessary. 最后,如果要注册多个函数,则必须使用List,数组或字典在C#和C ++端保存它们,然后在必要时迭代并调用每个函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM