• 締切済み

VCのDLLを呼ぶ場合の宣言方法

VB.NetからVC++で作成したDLLを使用する場合の宣言方法について教えてください。 VC++のDLLの関数で引数に構造体のポインタを渡すようになっているのですがマーシャリング属性の指定方法がわからなく困っています。 VB6.0では使用できたのでDLL側は問題ないと思うので(DLL側は修正ししないでVB側の修正で対応したいです)VB.Net側の問題だと思うのですがどこを直したらいいのかご教授願えないでしょうか。 以下にVC++のDLLの宣言部、VB6.0のときのソース、VB.Netのソースの必要と思われる部分を載せておきます。 ただしVB.NetのソースはVB6.0からUpGradeしたものをWeb等で調べて修正したものです。 当方VBに関してはまだ触り始めて1ヶ月も経っていないのですが仕事で急ぎで対応しなくてはならないため勉強する時間がなくどうすればいいか困っています。 よろしくお願いします。 ### VC++側ソース(概略) void __stdcall GetData( STESTDATA* pData ) struct STESTDATA { float fData1[6]; float fData2[32][6]; }; ### VB6.0の時のソース Private Type testdata Data1(5) As Single Data2(5, 31) As Single End Type Private Declare Sub GetData Lib "TestLib.dll" (ByRef pData As testdata) Private Sub TimerGetData_Timer() Dim data As testdata GetData data End sub ### VB.Net(2008)の時のソース <StructLayout(LayoutKind.Sequential)> _ Private Structure testdata <MarshalAs(UnmanagedType.ByValArray)> Dim Data1() As Single <MarshalAs(UnmanagedType.ByValArray)> Dim Data2(,) As Single Public Sub Initialize() ReDim Data1(5) ReDim Data2(5, 31) End Sub End Structure <System.Runtime.InteropServices.DllImport("TestLib")> _ Private Shared Sub GetData(ByVal pData As testdata) End Sub Private Sub TimerGetData_Tick(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles TimerGetData.Tick Dim data As testdata data.data1 = New Single(5) {} data.data2 = New Single(5, 31) {} data.Initialize() GetData(data) End Sub ※因みにVB.Netのソースを実行すると本来ならdata構造体のdata1とdata2に値にDLL内で値が設定されるのですが、現状では全て0が設定されてしまっています。

みんなの回答

回答No.2

またまた未確認ですみませんが MarshalAs で UnmanagedType.ByValArray を使う場合は、SizeConstも指定する必要があるようです。

回答No.1

確認していませんが、ByRefにすれば基本的にポインタ渡しになるはずです。 <System.Runtime.InteropServices.DllImport("TestLib")> _ Private Shared Sub GetData(ByRef pData As testdata) End Sub

MOYAJI
質問者

お礼

Wizard_Zeroさん回答ありがとうございます。 VB6.0から移植した当時はByRefとしていたのですが、この関数をコールした時点でエラーとなってしまい、Webで調べてByValとしました。 (ByValで正しいかは不明だったのですが…) もしByRefが正しい場合、この関数をコールしたときにエラーとなるのは他に原因があるのでしょうか? もしご存知であれば教えていただけないでしょうか。