带字符串的C#编组结构到C库

时间:2018-08-03 08:08:15

标签: c# android c pinvoke marshalling

我正在编写一个必须从Unity3D(C#)进行交互的C库,并且在编写我的一个PInvoke调用时遇到了问题。

我有以下c结构

typedef struct TestStruct
{
    const char* Method;
    const char* Url;
} TestStruct;

和C函数签名

__declspec(dllexport) void __cdecl TestMethod(TestStruct* args)
{
    // Do stuff with Method and URL
}

在C#中,我像这样创建了我的结构

[StructLayout(LayoutKind.Sequential)]
public struct TestStruct
{
    public string Method;
    public string Url;
}

像这样PInvoke签名

[DllImport("Test", CallingConvention = CallingConvention.Cdecl)]
private static extern void TestMethod(TestStruct args);

现在,当我在Win64上的Unity编辑器中运行它时,它就可以正常工作。但是,当我将其部署到我的android设备(我相信是32位ARM架构的Nexus 6)上时,当它们到达C库时,我的测试结构中的Method和Url属性为空。

奇怪的是,如果我更改函数签名以使用原始参数来完全避免使用该结构,那么它就可以正常工作。

__declspec(dllexport) void __cdecl TestMethod(const char* Method, const char* Url)
{
    // Do stuff with Method and URL
}

[DllImport("Test", CallingConvention = CallingConvention.Cdecl)]
private static extern void TestMethod(string method, string url);

工作正常。有人知道我在做什么错吗?

1 个答案:

答案 0 :(得分:1)

此:

__declspec(dllexport) void __cdecl TestMethod(TestStruct* args)

等效于:

[DllImport("Test", CallingConvention = CallingConvention.Cdecl)]
private static extern void TestMethod(ref TestStruct args);

out TestStruct,具体取决于谁将写入TestStruct

重要:如果将string传递给C-> C#,则C#不应修改它们(否则,.NET将尝试使用错误的分配器释放它们,否则将发生不良情况)。如果您使用out TestStruct,C端将不得不取消分配返回的const char*,我不得不说我不知道​​到底是什么原因(因为您在Windows下使用Unity而不是.NET,所以事情变得有点毛茸茸了)