C中如何在Unity3d中调用GL.IssuePlugInEvent并将参数传递给插件端
How to call GL.IssuePlugInEvent in Unity3d and pass parameters to the plugin side in C
我正在尝试为 Unity 编写一个插件,用于在 android 的本机端(但同样适用于任何其他 dll 或 so 库)和统一端之间传递信息。我要分享的信息是 OpenGL 相关的。在 Unity 文档中指定渲染线程上必须 运行 的所有内容都必须通过 GL.IssuePlugInEvent
函数调用。这个函数虽然对参数非常严格:它需要调用具有特定签名的函数:
Callback must be a native function of "void UNITY_INTERFACE_API UnityRenderingEvent(int eventId)" signature
并且只有附加参数 eventId。
然后如何从 so 库传回 unity 方面的信息?
用于创建插件和使用 IssuePluginEvent 的 Unity 示例涵盖了您 want/need 直接调用 C 函数的情况,并且该函数仅接受 eventId 作为参数。如果 reader 来自 C\C++ 背景并且不熟悉 C#,则可能会产生误导。事实上,您实际上可以使用这个简单的技巧调用 C# 函数,并在该函数内部调用传递多个参数的 C 函数。
步骤是:
- 获取 C# 函数的函数指针(注意该函数将是静态的)
- 将该函数指针传递给 GL.IssuePluginEvent
- 在静态 C# 函数中,根据 eventId 的大小写,调用适当的 C 函数
void Update()
{
GL.IssuePluginEvent(RenderThreadHandlePtr, GL_INIT_EVENT); // example
}
/// <summary> Renders the event delegate described by eventID. </summary>
/// <param name="eventID"> Identifier for the event.</param>
private delegate void RenderEventDelegate(int eventID);
/// <summary> Handle of the render thread. </summary>
private static RenderEventDelegate RenderThreadHandle = new RenderEventDelegate(RunOnRenderThread);
/// <summary> The render thread handle pointer. </summary>
public static IntPtr RenderThreadHandlePtr = Marshal.GetFunctionPointerForDelegate(RenderThreadHandle);
public const int GL_INIT_EVENT = 0x0001;
public const int GL_DRAW_EVENT = 0x0002;
/// <summary> Executes the 'on render thread' operation. </summary>
/// <param name="eventID"> Identifier for the event.</param>
[MonoPInvokeCallback(typeof(RenderEventDelegate))]
private static void RunOnRenderThread(int eventID)
{
switch (eventID)
{
case GL_INIT_EVENT:
glInit(par1, par2, par3); // C function with 3 parameters
break;
case GL_DRAW_EVENT:
glStep();
GL.InvalidateState();
break;
}
}
[DllImport("hello-jni")]
private static extern void glInit(int par1, int par2, int par3);
[DllImport("hello-jni")]
private static extern void glStep();
我正在尝试为 Unity 编写一个插件,用于在 android 的本机端(但同样适用于任何其他 dll 或 so 库)和统一端之间传递信息。我要分享的信息是 OpenGL 相关的。在 Unity 文档中指定渲染线程上必须 运行 的所有内容都必须通过 GL.IssuePlugInEvent
函数调用。这个函数虽然对参数非常严格:它需要调用具有特定签名的函数:
Callback must be a native function of "void UNITY_INTERFACE_API UnityRenderingEvent(int eventId)" signature
并且只有附加参数 eventId。
然后如何从 so 库传回 unity 方面的信息?
用于创建插件和使用 IssuePluginEvent 的 Unity 示例涵盖了您 want/need 直接调用 C 函数的情况,并且该函数仅接受 eventId 作为参数。如果 reader 来自 C\C++ 背景并且不熟悉 C#,则可能会产生误导。事实上,您实际上可以使用这个简单的技巧调用 C# 函数,并在该函数内部调用传递多个参数的 C 函数。 步骤是:
- 获取 C# 函数的函数指针(注意该函数将是静态的)
- 将该函数指针传递给 GL.IssuePluginEvent
- 在静态 C# 函数中,根据 eventId 的大小写,调用适当的 C 函数
void Update()
{
GL.IssuePluginEvent(RenderThreadHandlePtr, GL_INIT_EVENT); // example
}
/// <summary> Renders the event delegate described by eventID. </summary>
/// <param name="eventID"> Identifier for the event.</param>
private delegate void RenderEventDelegate(int eventID);
/// <summary> Handle of the render thread. </summary>
private static RenderEventDelegate RenderThreadHandle = new RenderEventDelegate(RunOnRenderThread);
/// <summary> The render thread handle pointer. </summary>
public static IntPtr RenderThreadHandlePtr = Marshal.GetFunctionPointerForDelegate(RenderThreadHandle);
public const int GL_INIT_EVENT = 0x0001;
public const int GL_DRAW_EVENT = 0x0002;
/// <summary> Executes the 'on render thread' operation. </summary>
/// <param name="eventID"> Identifier for the event.</param>
[MonoPInvokeCallback(typeof(RenderEventDelegate))]
private static void RunOnRenderThread(int eventID)
{
switch (eventID)
{
case GL_INIT_EVENT:
glInit(par1, par2, par3); // C function with 3 parameters
break;
case GL_DRAW_EVENT:
glStep();
GL.InvalidateState();
break;
}
}
[DllImport("hello-jni")]
private static extern void glInit(int par1, int par2, int par3);
[DllImport("hello-jni")]
private static extern void glStep();