C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


(過去ログ 127 を表示中)
■75371 / )  Re[6]: VB.netからVC++6.0のへの構造体配列参照渡し
□投稿者/ 魔界の仮面弁士 (248回)-(2015/03/19(Thu) 11:50:26)
No75321 (魔界の仮面弁士) に追記
> MarshalAs 指定は必要になるだろうということで、SafeArray 指定で
>  ・SafeArray
>  ・SafeArray, SafeArraySubType:=VT_USERDEFINED
>  ・SafeArray, SafeArraySubType:=VT_RECORD, SafeArrayUserDefinedSubType:=GetType(Structure1)
> などを試してみましたが、HRESULT が E_INVALIDARG(0x80070057) を返すばかり。

焦って試行錯誤してるけど、理論武装無しで闇雲に試しても駄目だよなぁ…。


そもそも構造体のセーフ配列について知識が全然無いので、
VB6 当時のマーシャリングがどうなっているかを調査してみるかな。


まずは VB6 の VarType 関数を使って、バリアントの内部型を確認。

ユーザー定義型に対して VarType を使うためには、その型を
パブリックオブジェクトモジュールで公開しておく必要があるので、
今回は ActiveX EXE プロジェクトにてテスト。

'=== クラス モジュール(Instacing を「1:Private」以外に設定) ===
Option Explicit
' No75314 のユーザー定義型
Public Type Type1
 Long1 As Long
 Long2 As Long
 Long3 As Long
End Type

'=== 標準モジュール ===
Option Explicit
Public oType(0 To 9) As Type1
Private Sub Main()
 Debug.Print Hex(VarType(oType))
 Debug.Print TypeName(oType)
End Sub


結果は、VarType = &H2024、TypeName = "Type1()" 。

&H2024 は、「vbArray Or vbUserDefinedType」のことなので、
VC++ 側の表現で言えば、「VT_ARRAY | VT_RECORD」相当だと分かる。



念のため、SafeArrayGetVartype API でも調べてみる。

 Declare Function SafeArrayGetVartypeVB Lib "oleaut32" Alias "SafeArrayGetVartype" _
  (oType() As Any, pvt As VBA.VbVarType) As Long

 Declare Function SafeArrayGetVartypeOLE Lib "oleaut32" Alias "SafeArrayGetVartype" _
  (oType() As Any, pvt As olelib.VARENUM) As olelib.HRESULTS

やはり、vbUserDefinedType = VT_RECORD = &H0024 が返されてきた。


ということは、.NET 側のマーシャリングでは、
 <MarshalAs(UnmanagedType.SafeArray, SafeArraySubType:=VarEnum.VT_RECORD)>
を指定すれば良さそうだ、ということまで理解。

でもまだうまく呼べない。次の手を考えないと。
返信 編集キー/


管理者用

- Child Tree -