私が使用しようとしているアンマネージ DLL があります。これは、それらの最後に予約されたメンバーを持ついくつかのネストされた構造体を利用します。それらを C# に変換する際に問題が発生しています。
コードを本質的なものに落とし込もうとしました。ParentStruct には、3 つの異なる子構造体の 4 つのインスタンスのメンバーがあります。これら 3 つの異なる子構造体はすべて、将来の使用のためにメモリを予約するための void* 配列を持っています。
予約済みの値を IntPtrs として実行しようとしましたが、安全でないコードを有効にして、fixed キーワードを使用してみました (そしてそれらを int に変更しました)。構造体の最後に適切な数の連続する IntPtrs を実際にレイアウトしてみました。何も機能していないようです。
これらのケースのいくつかでは、エラー メッセージ (特定のスレッドの特定のアドレスでエラーが発生したことを示す、有益でないメッセージ) が表示されます。ただし、ほとんどの場合、アプリケーションはエラー メッセージなしで終了します。ここでアンマネージメモリをいじっているためだと思います。
参考までに、実際の Pinvoke には次のような署名があります。
[DllImport("MyDll.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
internal static extern void UseStructs([In,Out] ref ParentStruct parent);
では、これらの構造体を使用できるように C# でこれらの構造体を宣言する正しい方法は何ですか?
typedef struct
{
ChildStruct1 childOne;
ChildStruct2 childTwo;
ChildStruct2 childTwoB;
ChildStruct3 childThree;
#if defined K_64_BIT
/// Reserved for future implementation
void* Reserved[15];
#elif defined K_32_BIT
/// Reserved for future implementation
void* Reserved[14];
#endif
} ParentStruct;
typedef struct
{
bool Valid;
float x;
float y;
/// Reserved for future implementation.
void* Reserved[16];
} ChildStruct3;
typedef struct
{
bool Found;
XYPairFloat xyPair;
/// Reserved for future implementation.
void* Reserved[16];
} ChildStruct2;
typedef struct
{
unsigned char* imageData;
RectInt rectInt;
#if defined QUICK_LINK_64_BIT
/// Reserved for future implementation
void* Reserved[14];
#elif defined QUICK_LINK_32_BIT
/// Reserved for future implementation
void* Reserved[12];
#endif
} ChildStruct1;
typedef struct
{
int x;
int y;
int width;
int height;
} RectInt;
typedef struct
{
float x;
float y;
} XYPairFloat;
編集:少なくとも人間が読めるエラーメッセージが表示されるようになったという点で、私は近づいたと思います。しかし、それでもうまくいきません。Reserved メンバーで fixed キーワードを使用し、メンバーの属性の SizeConst 部分を適切に設定しました。私が行った他のすべては、基本的な pinvoke 作業にすぎません。ただし、次のエラーが表示されます。
このフィールドの型定義にはレイアウト情報がありますが、マネージド型とアンマネージド型の組み合わせが無効であるか、マーシャリングできません。
最初のメンバーである ChildStruct1 childOne メンバーを参照して、他のメンバーにも当てはまると思います。考え?
編集 2: Mark Heath の要求に従って、ChildStruct1 に使用している実際の定義は次のとおりです。
[StructLayout(LayoutKind.Sequential)]
internal unsafe struct ChildStruct1
{
[MarshalAs(UnmanagedType.LPStr)]
public string imageData;
public RectInt rectInt;
[MarshalAs(UnmanagedType.LPArray, SizeConst=12)]
public fixed int Reserved[12];
}
編集 3:もう少し掘り下げました。Reserved メンバーをコメントアウトすると、エラーが表示されなくなります。明らかにうまくいきません。しかし、その特定のエラーは、そのメンバーをどのように定義したかによって引き起こされたと思います。