構造体のマーシャリング

解決


VB6使いのVB.net初心者  2004-02-05 00:30:40  No: 81826  IP: [192.*.*.*]

質問させてください。

VB.net2003にて、構造体をアンマネージDLLに渡そうとしているのですが、
マーシャリングできないというエラーが出ます。

何をしているかというと、複数のVB.netアプリで情報を共有する必要があり、
それを実現する方法として、ファイルマッピングを使用しています。
(他に.netならではの方法があるのかもしれませんが、納期が短いのと、
自分がVB6使いなもので・・・^^;)


''24バイトの構造体
<StructLayout(LayoutKind.Sequential)> Structure Person
    Dim Age As Integer
    <VBFixedString(20), MarshalAs(UnmanagedType.ByValTStr, SizeConst:=20)> _
    Dim Name As String
End Structure


''一人24バイト×4人で、96バイトの構造体、のつもり
<StructLayout(LayoutKind.Sequential)> Structure PersonDB
    <VBFixedArray(3), MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> _
    Dim Persons() As Person
    Public Sub Init()
        ReDim Persons(3)
    End Sub
End Structure

''メモリコピー関数
Declare Sub MemCopy Lib "kernel32" Alias "RtlMoveMemory" _
(ByVal hpvDestAs Integer,ByRef hpvSource As PersonDB,  ByVal cbCopy As Integer)

Sub Main()
    
    Dim DB As PersonDB
    Dim Ret As Integer
    Dim Pt As Integer

    DB.Init()
    ''ここで適当にDBに対して値代入処理

    Pt = マップファイルへのポインタ
    ''DBの内容をマップファイルに書き込み
    Call MemCopy(Pt, DB ,Len(DB))

End Sub

Call部でマーシャリングできないというエラーが出ます。
構造体の中に構造体配列がない場合はうまくいきます。
某掲示板でも、構造体の中に構造体配列があるとマーシャリングが
うまくいかないという発言がありました。
やはり不可能なのでしょうか?
構造体配列をアンマネージDLLに渡す方法をご教授お願いします。

編集    削除
Y2  2004-02-05 02:06:46  No: 81827  IP: [192.*.*.*]

<VBFixedArray(3), MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> _
の行を消してみると大丈夫かもしれないです

編集    削除
VB6使いのVB.net初心者  2004-02-05 03:01:38  No: 81828  IP: [192.*.*.*]

Y2さん

レスありがとうございます。
おっしゃられた事を試してみましたが、

「オブジェクト参照がオブジェクト インスタンスに設定されていません」

というエラーが出るようになりました。
違うっぽいです・・・

編集    削除
魔界の仮面弁士  2004-02-05 06:24:53  No: 81829  IP: [192.*.*.*]

StructLayoutAttribute属性クラスのPackフィールドの値が、DLL側が要求するアライメントと一致しているか確認してみてください。
例えば、SHFILEOPSTRUCT構造体などは 1バイト単位に設定する必要があります。

それから、ハンドルをMemCopyに渡す際に、GCHandleでガベージコレクトをロックしているかどうかも確認してください。
あと、MemCopyを呼び出す必要があるのかどうかも調べた方が良いかと。
(Marshalクラスで十分な場合もありますし)

編集    削除
Y2  2004-02-06 00:55:53  No: 81830  IP: [192.*.*.*]

やっぱり、自力でマーシャリングするしかないんですかね?(´Д`)
Marshalクラスのメソッドを使って配列中の構造体一つ一つをマーシャリングすれば大丈夫だと思います。
↓のサンプルが参考になるかもしれないです。
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpguide/html/cpconoutarrayofstructssample.asp
MarshalAsAttributeのArraySubTypeを設定して簡単に出来たような気もしますけど...

編集    削除
VB6使いのVB.net初心者  2004-02-06 21:57:18  No: 81831  IP: [192.*.*.*]

魔界の仮面弁士さん  Y2さん

レスありがとうございます。
書籍でも調べてみましたが、配列中の構造体を一つ一つ手動で
マーシャリングする必要があるみたいですね・・・

とりあえず、Y2さんのレスのサンプルと書籍を参考にして、
手動でマーシャリングしてみることにします。

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

編集    削除