I'm trying to write a plugin for Unity that passes information between the native side of android (but same may apply to any other dll or so library) and the unity side. The information I want to share is OpenGL related. On Unity docs it's specified that everything that has to run on the rendering thread must be called through The GL.IssuePlugInEvent
function. This function though is quite strict on the parameters: it needs a to call a function with a specific signature:
Callback must be a native function of "void UNITY_INTERFACE_API UnityRenderingEvent(int eventId)" signature
and has only the additional parameter eventId.
How can I then pass back on the unity side information from the so library?
The Unity examples for creating a plugin and using IssuePluginEvent cover the case where you want/need to call directly a C function, and this function accepts only an eventId as parameter. If the reader comes from a C\C++ background and is not familiar with C#, it may be misleading. In fact, you can actually call a C# function with this simple trick, and inside that function call your C functions passing multiple parameters. The steps are:
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();