- PR -

構造体の配列を含む構造体をマーシャリングする方法

1
投稿者投稿内容
masataka
会議室デビュー日: 2006/02/17
投稿数: 13
投稿日時: 2006-02-17 13:35
VB.NET2003でVC++6.0で作成されたDLLを使用する処理を作成しています。
このDLL内の"構造体の配列を含む構造体"を引数とする関数呼び出しを行うと、実行時エラーが発生してしまいます。
御存知の方がいらっしゃいましたら教えて下さい。

[環境]
VisualStudio.NET2003、Windows2000

[エラーメッセージ(ダイアログ)]
'System.TypeLoadException'のハンドルされていない例外が vb.exe
で発生しました。
追加情報:型 DLLSTRUCT1 のフィールド array をマーシャリングできま
せん。:この型は構造体フィールドとして、マーシャリングできません。

[詳細]
・DLLの構造体宣言
<StructLayout(LayoutKind.Sequential, Pack:=4, CharSet:=CharSet.Auto)> _
Structure DLLSTRUCT_SUB
Dim dummy As Integer
End Structure

<StructLayout(LayoutKind.Sequential, Pack:=4, CharSet:=CharSet.Auto)> _
Structure DLLSTRUCT1
<MarshalAs(UnmanagedType.ByValArray, sizeconst:=2)> _
Dim array() As DLLSTRUCT_SUB
Public Sub Initialize()
ReDim array(2 - 1)
End Sub
End Structure

・DLLの関数宣言
Declare Function fnDllProc1 Lib "DllProc" Alias "_fnDllProc1@4" (ByRef ptr As DLLSTRUCT1) As Integer

・処理
Dim dpr1 As DLLSTRUCT1
Dim res1 As Long
dpr1.Initialize()
dpr1.array(0).dummy = 100002
dpr1.array(1).dummy = 100003
fnDllProc1(dpr1) ' ← この関数呼び出しでエラーになります。

Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2006-02-17 15:06
そういうものとして諦めてください。
なお.NET 2.0 からは MarshalAs 属性による固定長構造体配列メンバをサポートするようになります。

それまではどうするかというと、個数分の構造体フィールドを並べるのが(要素数が少ない場合は)一番手っ取り早いです。
IntPtr と Marshal クラスのメンバを駆使して自力でメモリを切り盛りする手もあります。この場合は構造体の扱い方も大きく変更せざるを得ないでしょう。
masataka
会議室デビュー日: 2006/02/17
投稿数: 13
投稿日時: 2006-02-17 15:38
御回答ありがとうございます。

とりあえずは個数分の構造体フィールドを並べる方法でいきます。
(ループが組めないので非常に面倒ですがしょうがないですね。)

ありがとうございました。
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2006-02-17 15:52
折角のVBなのですから、引数付きプロパティを実装するのも手です。

更に一歩進めて、それを別構造体にしてIEnumerableを実装するとかいう手もあります。
ま、たかだかアンマネージドとのマーシャリングのためにそんな事する必要があるとは思いませんが。
masataka
会議室デビュー日: 2006/02/17
投稿数: 13
投稿日時: 2006-02-17 18:16
引用:

Hongliangさんの書き込み (2006-02-17 15:52) より:
折角のVBなのですから、引数付きプロパティを実装するのも手です。



そうですね。
VBには引数付きプロパティがありました。
配列への参照を引数にする関数には渡せなかったとは思いますが、それでもかなり使いやすくなりますね。
(IEnumerableはちょっと面倒なので今回はやめておきます)

ありがとうございました。
masataka
会議室デビュー日: 2006/02/17
投稿数: 13
投稿日時: 2006-02-17 19:50
引用:

Hongliangさんの書き込み (2006-02-17 15:52) より:
折角のVBなのですから、引数付きプロパティを実装するのも手です。



そうですね。
VBには引数付きプロパティがありました。
配列への参照を引数にする関数には渡せなかったとは思いますが、それでもかなり使いやすくなりますね。
(IEnumerableはちょっと面倒なので今回はやめておきます)

ありがとうございました。
1

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