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

わんくま同盟

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

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


(過去ログ 127 を表示中)
■75372 / )  Re[7]: VB.netからVC++6.0のへの構造体配列参照渡し
□投稿者/ 魔界の仮面弁士 (249回)-(2015/03/19(Thu) 11:53:45)
No75371 (魔界の仮面弁士) に追記
> ということは、.NET 側のマーシャリングでは、
>  <MarshalAs(UnmanagedType.SafeArray, SafeArraySubType:=VarEnum.VT_RECORD)>
> を指定すれば良さそうだ、ということまで理解。
> でもまだうまく呼べない。次の手を考えないと。

チラ裏投稿の続き。


この段階で、VB.NET 側の実装はこのように書いている。

 Declare Function Test1 Lib "TestFunc.dll" _
  (<MarshalAs(UnmanagedType.SafeArray, SafeArraySubType:=VarEnum.VT_RECORD)> _
  ByRef Type1() As Structure1) As Integer

 Public Structure Structure1
  Dim Long1 As Integer
  Dim Long2 As Integer
  Dim Long3 As Integer
 End Structure

結果は、『パラメーターが間違っています。』な E_INVALIDARG(0x80070057) の例外。


…あぁ、そういえば構造体を COM 公開していなかった。

<ComVisible(True), Guid("8D60602D-452A-48A1-ACEF-AF148A6E41B8")> _
Public Structure Structure1
 Dim Long1 As Integer
 Dim Long2 As Integer
 Dim Long3 As Integer
End Structure


まだ駄目か。 No75336 に書いたとおり、RegAsm もしておこう。
「RegAsm ConsoleApplication1.exe」…っと。

--------------------
  RegAsm : warning RA0000 : 型は何も登録されませんでした。
--------------------

あれ?なんか忘れてるっけ?

わかった、構造体を「Module Module1」の中で宣言しているからだ。
「Public Module Module1」にしないと意味が無いわな。


Module のスコープを Public に直して再実行。

 Dim iRet As Integer = -1
 For n = 0 To 9
  oType(n).Long1 = n * 100 + 1
  oType(n).Long2 = n * 100 + 2
  oType(n).Long3 = n * 100 + 3
 Next
 iRet = Test1(oType)

おぉ、エラーなく呼べた!!
配列が 10 件→1 件になる現象も起きていない!


…いや、ちょっと待てよ。そういえば、Public Module 化した後、RegAsm 呼んでなかったな。
もしかして COM 公開って意味が無いのだろうか。

確認のため、COM 公開を止めてみよう。
 <ComVisible(False)> _
 Public Structure Structure1
  Dim Long1 As Integer
  Dim Long2 As Integer
  Dim Long3 As Integer
 End Structure

……うん。やっぱりコレだと E_INVALIDARG(0x80070057) の例外が発生する。
ComVisible は必要っぽいな。RegAsm や TlbExp はしなくても大丈夫そう。


呼び出しまではできるようになったので、次は、DLL からの情報を受け取れるかどうかの確認だな。
返信 編集キー/


管理者用

- Child Tree -