It seems that my C SDKs may be unusable for Unity iOS (without a bit of an overhaul), but I wanted to verify to be sure. The long story short: I can compile and run my Unity sample that uses native code with function pointers for callbacks, but when it comes time to trigger my C# callback I get the following error:
ExecutionEngineException: Attempting to JIT compile method ‘(wrapper native-to-managed) gamespySample.CreateUserAccount:createuserCallback (Gamespy.GHTTPResult,intptr,intptr)’ while running with --aot-only.
The same code works on PC (with c code compiled into a DLL) and Android (with c code compiled into a .so), but it seems the iOS is limited to aot compiling which does not allow for this function pointer-to-delegate marshaling. Some web searching led me to this issue being a known limitation of MonoDevelop/iOS, which can be solved by using the ‘MonoPInvokeCallback’ attribute (within the MonoTouch namespace) for the C# delegate, but it seems this namespace is unavailable within the Unity version of MonoDevelop.
Is it in fact not possible to use function pointers in Unity iOS? If this is the case, I presume I’ll need to write a layer of c wrappers that handle the function pointer callbacks and just return the needed data (after getting polled).
For reference, I’ll include an example function below:
C declaration:
WSCreateUserAccountValue wsCreateUserAccount(…, WSCreateUserAccountCallback userCallback);
where WSCreateUserAccountCallback is the function pointer:
*typedef void (WSCreateUserAccountCallback)(…);
Then in our C# wrapper we have the following declarations:
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
public delegate void WSCreateUserAccountCallback(GHTTPResult httpResult, IntPtr theResponse, IntPtr userData);
[DllImport (“__Internal”)]
public static extern void wsCreateUserAccount(…, WSCreateUserAccountCallback callback);
And lastly here’s our C# invokation:
WSCreateUserAccountCallback myCreateUserAccountCallback = new WSCreateUserAccountCallback(createuserCallback);
wsCreateUserAccount(…, myCreateUserAccountCallback);
where createuserCallback is defined like:
public static void createuserCallback(…)
{
…
}