|
分類:[C#]
タイトルにもあるんですが、C#でDLLのAPIとやり取りするパラメータで渡す 構造体の型定義で上手くいかず悩んでます。
調べると普通の固定長の変数、文字列を含んだ定義の方法は解決したのですが、 構造体の中に固定長の構造体と言うケースだと、分からなくて…
<DLL APIでのC言語定義> typedef tagInfo { int nA; int nB; double dC; }INFO,*PINFO;
typedef tagInfoData { char szFilePath[260]; char szTitle[80]; int Value[100]; int nD; long lE; INFO Info[5]; }INFO_DATA,*PINFO_DATA;
BOOL GetInfoData( PINFO_DATA pInfoData );
<C#呼び出し側での定義> [StructLayout( LayoutKind.Sequential, Pack = 1 )] public struct Info { int nA; int nB; double dC; }; [StructLayout( LayoutKind.Sequential, Pack = 1 )] public struct InfoData { [MarshalAs( UnmanagedType.ByValTStr, SizeConst = 260 )] public string strFilePath; [MarshalAs( UnmanagedType.ByValTStr, SizeConst = 80 )] public string strTitle; [MarshalAs( UnmanagedType.ByValArray, SizeConst = 100 )] public int[] Value; int nD; long lE; [MarshalAs( UnmanagedType.ByValArray, SizeConst = 5 )] INFO[] Info; };
[DllImport("Test.dll")] private static extern bool GetInfoData( out InfoData );
上記のように定義すると、コンパイルエラーにはならないのですが、 API関数を呼び出すと「追加情報 : この操作を完了するのに十分な 記憶域がありません。」と言う例外が発生してしまいます。 配列「INFO[] Info」を「INFO Info1〜Info5」と非配列にすれば 例外も出ず動作自体も正常に動くんですが、どうしてもコードが 汚くなってしまう(配列でないからループにできない)ので、 配列にできれば…と思ってます。
上記の解決法、理由が分かる方はぜひ教えてください。
なお開発環境が WindowsXP Visual Studio.NET2003のため、C#2.0より使用できる 「fixed」宣言が使えません。
|