我正在研究一个.NET DLL来访问我给出的C++库。在C++库,有这样的结构:当传递给结构中的非托管代码时,C#中的字节数组会发生什么?
typedef struct FOO
{
DWORD DataSize;
BYTE *pData;
}
我在C#这样重建它:
[StructLayout(LayoutKind.Sequential)]
public struct FOO
{
public uint DataSize;
public byte[] pData;
}
我从C++ DLL导入旁边。我也将包含C++端的头文件。在C++中的方法需要一个指向我传递,所以从我已经能够收集在这种情况下会工作经过参考结构:
// C++ Header
HRESULT CallFoo(FOO * pFoo);
[DllImport("SomeLibrary.DLL", EntryPoint = "CallFoo")]
private static extern uint CallFoo(ref FOO rFoo);
当我踏进我的代码C++方面,我得到的结构,但在pData中的值是一个内存地址。这似乎是在C++库中的代码弄脏了,但我无法理解它返回给我的HRESULT(我已经向C++库的所有者提出了关于错误消息的问题)。
我根据this question's answer采取的另一种方法是尝试传递IntPtr而不是字节数组。我修改了结构:
[StructLayout(LayoutKind.Sequential)]
public struct FOO
{
public uint DataSize;
public IntPtr pData;
}
,并把它称为:
FOO fooParm = new Foo();
var ptr = IntPtr.Zero;
byte[] bArr = MethodThatReturnsAByteArray();
ptr = Marshal.AllocHGlobal(bArr.Length);
Marshal.Copy(bArr, 0, ptr, bArr.Length);
fooParm.pData = ptr;
fooParm.DataSize = bArr.Length;
uint i = CallFoo(fooParm);
这不幸的是不工作要么。我得到与原始方法相同的错误代码。
我不想使用这些自定义结构,但不幸的是该库不是我控制的东西。我已经为它编写了一个托管的C++包装器,我可能可以在调用库之前处理翻译,我也会看看这种方法。 – Wint