C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: 構造体内に固定個数構造体メンバ定義


(過去ログ 79 を表示中)

[トピック内 9 記事 (1 - 9 表示)]  << 0 >>

■46969 / inTopicNo.1)  構造体内に固定個数構造体メンバ定義
  
□投稿者/ ホエホエ (3回)-(2010/02/15(Mon) 14:07:34)

分類:[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」宣言が使えません。
引用返信 編集キー/
■46975 / inTopicNo.2)  Re[1]: 構造体内に固定個数構造体メンバ定義
□投稿者/ みきぬ (783回)-(2010/02/15(Mon) 15:52:51)
自分が同じ状況にハマったときは、↓を参考にして頑張ってました。
http://www2u.biglobe.ne.jp/~kaduhiko/csharp_05.html
引用返信 編集キー/
■46976 / inTopicNo.3)  Re[1]: 構造体内に固定個数構造体メンバ定義
□投稿者/ aetos (235回)-(2010/02/15(Mon) 15:57:47)
No46969 (ホエホエ さん) に返信
C# 側の宣言がいろいろと怪しい気が。
・StructLayout 属性に CharSet 指定をつけた方がいいかも。
・Pack = 1 は C 側でも指定されていますか?(#pragma pack(1) とか)
・C の long は 32bit では? その場合、C# 側の lE は int にすべきです。
引用返信 編集キー/
■46983 / inTopicNo.4)  Re[2]: 構造体内に固定個数構造体メンバ定義
□投稿者/ ホエホエ (4回)-(2010/02/15(Mon) 16:59:10)
ご返信ありがとうございます。

やはり構造体の配列はマーシャリングできないんですね…残念。
載せていただいたサイトの方法で頑張ってみたいと思います。
引用返信 編集キー/
■46984 / inTopicNo.5)  Re[2]: 構造体内に固定個数構造体メンバ定義
□投稿者/ ホエホエ (5回)-(2010/02/15(Mon) 17:05:04)
aetosさん>

ご返信ありがとうございます。

アライメントの方はどちらもPackは1に合わせております(情報が足りず申し訳ありません)

確かにCでのlongはC#ではintですね。質問用に例として書いたので抜けてました。
引用返信 編集キー/
■46988 / inTopicNo.6)  Re[3]: 構造体内に固定個数構造体メンバ定義
□投稿者/ Hongliang (562回)-(2010/02/15(Mon) 17:46:15)
> やはり構造体の配列はマーシャリングできないんですね…残念。
> 載せていただいたサイトの方法で頑張ってみたいと思います。
リンク先のページは今回の問題とは関係ありません。リンク先のものは動的配列の問題であり、このスレッドの話題は静的配列の問題だからです。
そして構造体の静的配列なら UnmanagedType.ByValArray によるマーシャリングが可能です。
// .NET1.x のときでも、少なくともこの Info のような単純な構造体なら問題なかったはず。

このコードは「質問用の例」らしいので、本来のものに何らかの記述上の瑕疵がある可能性も考えられます。
引用返信 編集キー/
■46989 / inTopicNo.7)  Re[4]: 構造体内に固定個数構造体メンバ定義
□投稿者/ みきぬ (785回)-(2010/02/15(Mon) 18:01:45)
No46988 (Hongliang さん) に返信
>>やはり構造体の配列はマーシャリングできないんですね…残念。
>>載せていただいたサイトの方法で頑張ってみたいと思います。
> リンク先のページは今回の問題とは関係ありません。リンク先のものは動的配列の問題であり、このスレッドの話題は静的配列の問題だからです。

おっと、失礼しました。
確かに私が遭った状況は要素数が可変でした。

ほかに思いつくところでは、ArraySubType = UnmanagedType.Struct を追加するとか。
引用返信 編集キー/
■47012 / inTopicNo.8)  Re[4]: 構造体内に固定個数構造体メンバ定義
□投稿者/ ホエホエ (6回)-(2010/02/16(Tue) 09:00:46)
Hongliang さん>
ご返信ありがとうございます。

例にもありますが、
[MarshalAs( UnmanagedType.ByValArray, SizeConst = 5 )]
INFO[] Info;
は試したのですが「追加情報 : この操作を完了するのに十分な記憶域がありません。」と
言う例外が発生してしまいます。Info自体はintやdoubleだけの単純な構造体です。

他に何か記述が不足しているのでしょうか?
引用返信 編集キー/
■47013 / inTopicNo.9)  Re[5]: 構造体内に固定個数構造体メンバ定義
□投稿者/ ホエホエ (7回)-(2010/02/16(Tue) 09:05:44)
みきぬさん>
再度のご返信ありがとうございます。

ご指摘通り
[MarshalAs( UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 5 )]
INFO[] Info;
としてみましたが、やはりダメでした。今回の情報を元にもう少し頑張ってみます。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -