- PR -

構造体メンバに構造体配列を持っている場合

1
投稿者投稿内容
らら
常連さん
会議室デビュー日: 2005/01/21
投稿数: 28
お住まい・勤務地: 埼玉県
投稿日時: 2005-02-24 14:55
こんにちは。

マネージ側(C#)⇔アンマネージ側(C++)でデータをやりとりしようとしてます。

C++では
STRUCT_API int StructIN( MYPERSON2 *myperson )
{
//...mypersonを使って処理
}

typedef struct _PERSON
{
char name[128];
char blood;
}PERSON;
typedef struct _MYPERSON
{
int age;
PERSON person[2];
}MYPERSON;
という感じで、PERSON型の配列をメンバに持つMYPERSON構造体を宣言しており,
StructIN関数は、そのMYPERSONのアドレスをパラメータで受け取ります。
ここで、マネージ側とアンマネージ側でやりとりをするためにマーシャリングを行う
と思うのですが、構造体配列をメンバにもつ構造体の宣言方法がわかりません。

C#では
[DllImport("STRUCT.dll", CharSet=CharSet.Ansi)]
public static extern int StructIN( ref MyPerson myperson);

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct Person
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)] public string name;
public char blood;
}

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct MyPerson
{
public int age;
public Person[] person; ←ここの宣言方法がわかりません。
}

C#でしたいことは、
MyPerson分の領域を確保(AllocCoTaskMem)してあげて、この構造体のアドレスをStructINに渡してあげたいです。

以下の方法で試してみましたがうまく行きませんでした。
@public Person[] person;
public void Reset(){ person = new Person[2];}
→Marshal.SizeOf(new MyPerson)した時に正しいサイズが取れない
→C++側に構造体の実体が渡らない
A[MarshalAs(UnmanagedType.ByValArray, SizeConst=2)] public Person[] person;
→アンマネージ構造体として集成できません。(エラー内容)

ご存知の方、是非ご教授お願いいたします。
らら
常連さん
会議室デビュー日: 2005/01/21
投稿数: 28
お住まい・勤務地: 埼玉県
投稿日時: 2005-02-24 14:58
先ほどのスレッドで入力ミスがありました。
訂正します。

 × STRUCT_API int StructIN( MYPERSON2 *myperson )

 ○ STRUCT_API int StructIN( MYPERSON *myperson )


以上、よろしくお願いします。
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2005-02-24 15:13
構造体配列を持つ構造体を渡す場合、構造体配列をポインタ型System.IntPtrで渡す事になります。
こちらが参考になるでしょう。
http://www2u.biglobe.ne.jp/~kaduhiko/csharp_05.html

余談ですが、.NET2.0ではUnmanagedType.ByValArrayで構造体配列をメンバに持った構造体をマーシャリングできるようになるようです。
らら
常連さん
会議室デビュー日: 2005/01/21
投稿数: 28
お住まい・勤務地: 埼玉県
投稿日時: 2005-02-24 15:17
Hongliangさん
ご返信ありがとうございます。

早速見てみます。



らら
常連さん
会議室デビュー日: 2005/01/21
投稿数: 28
お住まい・勤務地: 埼玉県
投稿日時: 2005-02-24 15:27
Hongliangさん

さきほど紹介していただいたページを見たのですが、私もおととい見つけて
挑戦してみたのですが、C側の構造体の構造体配列はポインタで受け取らなければならないのですよね。

実は、Cの方のDLLは他社様作成のDLLであり関数なのでいじれないのです。
なので、どうしてもC側も構造体配列は配列として受けてあげなくてはならないのです。

Cに手を入れられないのは結構痛いですよね。
2週間ほど検証してみたのですが、Cに手を加えないと今のところできなそうですね。
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2005-02-24 16:06
Cでは、配列変数a[]は結局の所アドレスaを先頭としたブロックを表しているに過ぎません。
*aとa[0]は等価で、*(a+1)とa[1]も等価です。
1

スキルアップ/キャリアアップ(JOB@IT)