【发布时间】:2011-01-21 05:49:12
【问题描述】:
我有一个导出以下函数的非托管 dll:
SomeData* test();
假设 SomeData 为:
typedef struct _Data Data;
struct _Data{
int a;
int b;
}
现在我想从 C# 代码调用这个函数。我开始定义自定义编组所需的 C# 结构,如下所示:
[StructLayout(LayoutKind.Sequential)]
public class SomeData
{
public Int32 a;
public Int32 b;
}
现在,我声明托管函数:
[DllImport("DynamicLibrary.dll", CharSet=CharSet.Auto)]
[return: MarshalAs(UnmanagedType.LPStruct)]
public static extern SomeData test();
在我的主要功能中:
IntPtr ptr = test();
这样做,我得到 MarchalDirectiveException:“无法封送'返回值':无效的托管/非托管类型组合(Int/UInt 必须与 SysInt 或 SysUInt 配对)。”
我没有在 C# 中为 SomeData 分配内存,因为我希望这个内存是在 C 函数中分配的,我会使用 Marshal.Copy 将它传递给托管内存。
有什么想法吗?谢谢
------------------------ JaredPar 回答后编辑 -------------------- -
事实上,我在处理我的问题的代码时犯了一个错误。我使用的真正托管签名是:
[DllImport("DynamicLibrary.dll", CharSet=CharSet.Auto)]
[返回:MarshalAs(UnmanagedType.LPStruct)]
公共静态外部 IntPtr 测试();
JaredPar 的答案仍然相关。为了获得正确的行为,我有 2 个选择:
1) 使用'public static extern IntPtr test();' (没有 MarshalAs 属性)签名,然后像 JaredPar 建议的那样访问返回的指针。
2) 使用'public static extern SomeData test();' (带有 MarshalAs 属性),然后简单地使用 SomeData sd = test();
【问题讨论】:
标签: c# pinvoke marshalling