c# - 使用 C++ 将 C# 方法编码到 Unity3D

标签 c# c++ linux unity3d marshalling

我想在外部插件中调用我的 Unity3D 项目中的特定方法。这是我的 C++ 代码:

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

我的 C++ 代码已经可以独立运行,但现在我想调用一个特定的 C# 方法。我怎样才能做到这一点?我试过像这样创建代表

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

但我不认为这是正确的方式...... 应该早点提到它,但我在 Linux-Fedora25 上编码

最佳答案

我过去在制作渲染插件时遇到过同样的问题,但解决方案并不难。

您需要创建一个全局static 函数指针 来保存您要从 C++ 调用的 C# 函数。 C++ 函数指针必须是 static。从 C# 中的 StartAwake 函数初始化此变量。之后,您可以随时从 C++ 中自由调用该函数。

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):

#include "YourCPP.h"

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

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

完成。您现在可以使用 callbackInstance 变量随时从 Unity 的 UNITY_INTERFACE_API OnRenderEventThreadSafe C++ API 函数调用 C# 函数。在像下面这样调用它之前,请确保它不是 null:

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

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

在使用 callbackInstance 变量之前,首先使用 RegisterRenderCallback 函数从 C# 向它注册一个函数。请参阅下面的 Start 函数中的示例。


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);
}

最后,如果要注册多个函数,则必须使用列表、数组或字典将它们保存在 C# 和 C++ 端,然后在必要时迭代并调用每个函数。

关于c# - 使用 C++ 将 C# 方法编码到 Unity3D,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48258980/

相关文章:

c++ - 如何将一些字符复制到 C++ 中的字符串中

c++ - 在 C++ 中,我无法选择特定变量用于用户输入

linux - 是否可以将套接字与 NIC 队列绑定(bind)?

javascript - 如何在没有 IDE 的情况下构建和部署三星 SmartTV 应用程序(例如 : on Linux)

c# - Windows 上的单声道(和一般问题)

c# - 如何使用 Selenium Webdriver .NET 绑定(bind)设置 Chrome 首选项?

c# - 当 WPF/xaml 中的值更改时更新行颜色

c++ - GetSystemDefaultLCID 返回错误数据 C++

c# - 使用继承自 List<T> 的类进行 JSON 序列化

c# - Marshal.SizeOf(Type t) 函数