C# 将带有字符串的结构编组到 C 库
C# Marshalling Structure with Strings to C Library
我正在编写一个 C 库,我必须从 Unity3D (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)时,方法和 Url 属性在我的测试结构中到达 C lib 时为 null。
奇怪的是,如果我更改我的函数签名以采用完全避免结构的原始参数,它工作得很好。
__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);
工作正常。有谁知道我可能做错了什么吗?
这个:
__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*
我不得不说我不知道具体如何(因为你使用的是 Unity 而不是 [=25 下的 .NET =], 所以事情变得有点毛茸茸)
我正在编写一个 C 库,我必须从 Unity3D (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)时,方法和 Url 属性在我的测试结构中到达 C lib 时为 null。
奇怪的是,如果我更改我的函数签名以采用完全避免结构的原始参数,它工作得很好。
__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);
工作正常。有谁知道我可能做错了什么吗?
这个:
__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*
我不得不说我不知道具体如何(因为你使用的是 Unity 而不是 [=25 下的 .NET =], 所以事情变得有点毛茸茸)