在C#中,如何调用返回包含字符串指针的非托管结构的DLL函数?

我得到了一个DLL(“InfoLookup.dll”),它在内部分配结构并从查找函数返回指向它们的指针。 结构包含字符串指针:

extern "C" { struct Info { int id; char* szName; }; Info* LookupInfo( int id ); } 

在C#中,如何声明结构布局,声明Interop调用,以及(假设返回非空值)使用字符串值? 换句话说,我如何将以下内容翻译成C#?

 #include "InfoLookup.h" void foo() { Info* info = LookupInfo( 0 ); if( info != 0 && info->szName != 0 ) DoSomethingWith( info->szName ); // NOTE: no cleanup here, the DLL is caching the lookup table internally } 

尝试以下布局。 使用PInvoke Interop Assistant自动生成代码。 手动编码的LookpInfoWrapper()

 [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public struct Info { /// int public int id; /// char* [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] public string szName; } public partial class NativeMethods { /// Return Type: Info* ///id: int [System.Runtime.InteropServices.DllImportAttribute("InfoLookup.dll", EntryPoint="LookupInfo")] public static extern System.IntPtr LookupInfo(int id) ; public static LoopInfoWrapper(int id) { IntPtr ptr = LookupInfo(id); return (Info)(Marshal.PtrToStructure(ptr, typeof(Info)); } } 

有关示例,请参阅此netapi32.NetShareAdd互操作声明。 它包含一个SHARE_INFO_502结构,带有一个public string shi502_netname成员。 Pinvoke.net提供了更多示例。

您还需要在C#中实现该结构,确保正确使用Marshal类中的属性以确保内存布局与非托管版本匹配。

所以,这有一些变化:

 using System.Runtime.InteropServices; [DllImport("mydll.dll")] public static extern Info LookupInfo(int val); [StructLayout(LayoutKind.Sequential)] struct Info { int id; String szName; } private void SomeFunction { Info info = LookupInfo(0); //Note here that the returned struct cannot be null, so check the ID instead if (info.id != 0 && !String.IsNullOrEmpty(info.szName)) DoSomethingWith(info.szName); }