I am writing a C library that I must interact with from Unity3D (C#) and am running into an issue with writing one of my PInvoke calls.
I have the following c struct
typedef struct TestStruct
{
const char* Method;
const char* Url;
} TestStruct;
And C function signature
__declspec(dllexport) void __cdecl TestMethod(TestStruct* args)
{
// Do stuff with Method and URL
}
In C# I've created my struct like so
[StructLayout(LayoutKind.Sequential)]
public struct TestStruct
{
public string Method;
public string Url;
}
And PInvoke signature like so
[DllImport("Test", CallingConvention = CallingConvention.Cdecl)]
private static extern void TestMethod(TestStruct args);
Now when I run this in the Unity editor on Win64 it works just fine. But when I deploy it to my android device (Nexus 6 which I believe is a 32 bit ARM architecture) the Method and Url properties are null in my test struct when they get to the C lib.
Strangely enough, if I change my function signatures to take the raw arguments avoiding the struct entirely, it works just fine.
__declspec(dllexport) void __cdecl TestMethod(const char* Method, const char* Url)
{
// Do stuff with Method and URL
}
and
[DllImport("Test", CallingConvention = CallingConvention.Cdecl)]
private static extern void TestMethod(string method, string url);
Works just fine. Does anyone have any ideas what I might be doing wrong?
This:
__declspec(dllexport) void __cdecl TestMethod(TestStruct* args)
is equivalent to:
[DllImport("Test", CallingConvention = CallingConvention.Cdecl)]
private static extern void TestMethod(ref TestStruct args);
or out TestStruct
, depending on who will write to the TestStruct
.
Important: if the string
s are passed C->C#, then C# shouldn't modify them (or .NET will try to free them with the wrong deallocator and bad things will happen). If you use out TestStruct
the C-side will have to deallocate the returned const char*
I'll have to say I don't know how exactly (because you are using Unity and not .NET under Windows, so the thing gets a little more hairy)