与えられた C++ ライブラリにアクセスする .NET DLL に取り組んでいます。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++ ライブラリの所有者に質問しました)。
この質問の回答に基づいて私が取った別のアプローチは、バイト配列の代わりに 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);
残念ながら、これも機能していません。元のアプローチと同じエラー コードが表示されます。