- PR -

2次元配列のマーシャリング方法

1
投稿者投稿内容
優希
ベテラン
会議室デビュー日: 2003/08/12
投稿数: 92
投稿日時: 2004-06-17 21:17
度々、お世話になります。

ネイティブコードで作成したDLLから、
データを取得しようとした場合にエラーとなり、
行き詰まっています。
ちょっとしたことでも良いので、
アドバイスをお願い致します。


開発環境:VC++.NET 2002
     Windows Form



DLL側の構造体中の変数で、
2次元配列の変数がある場合にエラーとなってしまいます。


エラー内容は、以下のとおりです。
引用:

型ManagedTblのフィールドFileNameをマーシャリングできません。
この型は構造体フィールドとして、マーシャリングできません。




まずはDLL側(Sample.dll)のソースです。

コード:
///
/// Native Codeで作成したDLL内の構造体
///
struct NativeTbl
{
    unsigned char  PathName[256];
    unsigned char  FileName[5][256];	// 2次元配列
};

///
/// 呼び出される関数(サンプル)
///
void GetFileData(struct NativeTbl *nativeInf)
{
  :
  :
    memset(nativeInf->PathName, ' ', 256);
    strcpy(nativeInf->PathName, aaa->path);

    for(int i=0; i<5; i++){
        memset(nativeInf->FileName[i], ' ', 256);
        strcpy(nativeInf->FileName[i], aaa->fileName[i]);
	}
}






次に呼び出し側のソースです。

コード:
///
/// Managed Codeで作成した構造体
///
[StructLayout(LayoutKind::Sequential, CharSet=CharSet::Auto)]
public __value struct ManagedTbl
{
public:
	[MarshalAs(UnmanagedType::ByValTStr, SizeConst=256)]
	String *PathName;
	[MarshalAs(UnmanagedType::ByValArray, 
	ArraySubType=UnmanagedType::LPStr, SizeConst=5)]
	String *FileName[];
};

///
/// DLL側関数のインポート
///
[DllImport("Sample.dll")]
static void GetFileData(ManagedTbl *managedInf);


///
/// 実行メソッド
///
void TestExec()
{
	// インスタンス生成
	ManagedTbl managedInf;
	managedInf.FileName = new String*[5];

  // DLL側の関数呼び出し
	GetFileData(&managedInf);	// ←ここでエラー

}




エラーにあるように、
2次元配列のマーシャリング方法が正しくないように思えます。

引用:

public __value struct ManagedTbl
{
   :
[MarshalAs(UnmanagedType::ByValArray, ArraySubType=UnmanagedType::LPStr, SizeConst=5)]
String *FileName[];
}



上記の構造体で、どのように記述するのか、
アドバイスをお願いします。
(VBやC#の記述でも構いません。)
宜しくお願い致します。
vikei
会議室デビュー日: 2008/04/03
投稿数: 1
投稿日時: 2008-04-03 16:48
あまり自信はありませんが、これでどうでしょうか。

(C#で説明させていただきます)

配列に対する既定のマーシャリング
http://msdn2.microsoft.com/ja-jp/library/z6cfh6e6(vs.80).aspx#cpcondefaultmarshalingforarraysanchor2

の中で
================
double ar[10][20]
================

================
[MarshalAs(UnmanagedType.LPArray, SizeConst=200)] double[] ar
================
と展開しているところから推測するに、問題の部分を
================
[MarshalAs(UnmanagedType::ByValTStr, SizeConst=(5 * 256))]String FileName;
================
というようにマーシャリングすれば、
とりあえずエラー回避はできるのではないかと思います。
マーシャリングの変換に多次元配列の概念がないとか、
そんなような記述をどこかで読んだがします。
なので一次元で最大サイズを確保すれば受け渡すだけならうまくいくのではないかと。
1

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