返回从非托管代码到托管代码的指针

我有一个非托管的DLL导出以下函数:

SomeData* test(); 

我们假设SomeData为:

 typedef struct _Data Data; struct _Data{ int a; int b; } 

现在我想用C#代码调用这个函数。 我开始定义自定义编组所需的C#Struture,如下所示:

 [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(); 

在主要function我有:

 IntPtr ptr = test(); 

这样做,我得到MarchalDirectiveException:“无法封送’返回值’:无效的托管/非托管类型组合(Int / UInt必须与SysInt或SysUInt配对)。”

我没有为C#中的SomeData分配内存,因为我希望这个内存在C函数中分配,我会使用Marshal.Copy将它传递给托管内存。

有任何想法吗? 谢谢

———————— JaredPar ANSWER之后的编辑——————–

事实上,我在将代码复制到我的问题时犯了一个错误。 我使用的真实托管签名是:

[DllImport(“DynamicLibrary.dll”,CharSet = CharSet.Auto)]
[返回:MarshalAs(UnmanagedType.LPStruct)]
public static extern IntPtr test();

JaredPar的答案仍然相关。 为了获得正确的行为,我有两个选择:

1)使用’public static extern IntPtr test();’ (没有MarshalAs属性)签名然后像JaredPar建议的那样访问返回的指针。

2)使用’public static extern SomeData test();’ (使用MarshalAs属性)然后只需使用SomeData sd = test();

声明托管函数时,需要将指针类型与参考值或IntPtr值匹配。 在这种情况下,LPStruct修饰符将无济于事。 最简单的解决方案是将test的返回值转换为IntPtr而不是SomeData因为本机方法返回指针值。 然后,您可以编写以下包装器

 [DllImport("DynamicLibrary.dll", CharSet=CharSet.Auto)] public static extern IntPtr test(); public static SomeData testWrapper() { var ptr = test(); try { return (SomeData)Marshal.PtrToStructure(ptr, typeof(SomeData)); } finally { // Free the pointer here if it's allocated memory } }