2008-12-10 33 views
3

我得到了一个DLL(“InfoLookup.dll”),它在内部分配结构并从查找函数返回指向它们的指针。该结构包含字符串指针:在C#中,如何调用一个返回包含字符串指针的非托管结构的DLL函数?

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

    Info* LookupInfo(int id); 
} 

在C#,如何可以声明结构布局中,声明互操作呼叫,和(假定一个非空值被返回)利用字符串值?换句话说,我如何将以下内容翻译成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 
} 

回答

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)); 
    } 

} 
-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); 
} 
+0

您不能将Marashal Info直接作为返回类型 – JaredPar 2008-12-10 17:35:00

2

有关示例,请参阅本netapi32.NetShareAdd互操作声明。它包括一个SHARE_INFO_502结构,一个public string shi502_netname成员。 Pinvoke.net有更多的例子。

相关问题