将C#结构的指针传递给C ++ API

时间:2013-06-11 00:09:26

标签: c# c++ interop pinvoke marshalling

这是我在C ++ dll中的结构和功能

struct Address
{
    TCHAR* szAddress;
};

extern "C" DllExport void SetAddress(Address* addr);

从C#我想通过传递地址结构来调用这个API。所以,我在C#中有以下内容

[StructLayout(LayoutKind.Sequential)] 
public struct Address
{
    [MarshalAs(UnmanagedType.LPTStr)]
    public String addressName;
}

[DllImport("Sample.dll")]
extern static void SetAddress(IntPtr addr);

现在,这就是我从C#调用C ++ API的方式

Address addr = new Address();
addr.addressName = "Some Address";
IntPtr pAddr = Marshal.AllocHGlobal(Marshal.SizeOf(addr));
Marshal.StructureToPtr(addr , pAddr , false);
SetAddress(pAddr); //CALLING HERE

我在C ++代码中为Address.szAddress获取NULL。知道这里出了什么问题吗?

1 个答案:

答案 0 :(得分:6)

您只需通过Address传递ref结构即可。您还需要确保调用约定匹配。它看起来好像本机代码是cdecl。最后,UnmanagedType.LPTStr表示Win9x上的ANSI和其他地方的Unicode。因此,如果本机代码需要UTF-16字符串,那么这是合适的。如果它需要ANSI,则使用UnmanagedType.LPStr代替。

此代码正常工作,本地代码接收C#代码中指定的字符串。

[StructLayout(LayoutKind.Sequential)]
public struct Address
{
    [MarshalAs(UnmanagedType.LPTStr)]
    public string addressName;
}

[DllImport(@"test.dll", CallingConvention=CallingConvention.Cdecl)]
extern static void SetAddress(ref Address addr);

static void Main(string[] args)
{
    Address addr;
    addr.addressName = "boo";
    SetAddress(ref addr);
}