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

时间:2008-12-10 17:21:04

标签: c# interop

我得到了一个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
}

4 个答案:

答案 0 :(得分:5)

尝试以下布局。使用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));
    }

}

答案 1 :(得分:2)

有关示例,请参阅此netapi32.NetShareAdd互操作声明。它包含SHARE_INFO_502结构,public string shi502_netname成员。 Pinvoke.net可以获得更多示例。

答案 2 :(得分:1)

答案 3 :(得分:-2)

您还需要在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);
}