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

わんくま同盟

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

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


(過去ログ 104 を表示中)
■62434 / )  Re[5]: C#からVBで作成したDLLへの構造体渡し
□投稿者/ コバピー (3回)-(2011/10/11(Tue) 09:17:52)
No62432 (魔界の仮面弁士 さん) に返信
> ■No62414 (コバピー さん) に返信
> >> テストコードを書いて試してみたところ、うちの環境では
> >> xxxx メソッドの引数は「ref Array dData」になっていました。
> ちなみに当方では、
> >>> public Function xxxx(ByRef dData() as Type_Data) 
> ではなく、
>  Public Function xxxx(ByRef dData() As Type_Data) As Integer
>   xxxx = -2
>   On Error Resume Next
>   xxxx = UBound(dData) - LBound(dData) + 1
>  End Function
> という宣言を用いて検証しました。
> 
> 
>>「objVBDll.xxxx(ref a);」と記述した行にカーソルを移動しますと
> 変数 a は System.Array 型なのですよね。
> 
>>「dynamic clsVBDll.xxxx(ref Array dData)」と表示されますので、
> 戻り値が dynamic なのが気になります。
> 
> VB6 側の Function の戻り値に As キーワードがありませんでしたが、
> 曖昧さを排除するためにも、VB6 側では戻り値を明示しておくべきかと思います。
> (互換性維持のために型を変更できない状況でも、型名自体は明記すべきです)
> 
>>エディタ上でのエラー表示も消えましたが、実行しますと、やはり「パラメータが間違っています」
> 実行時にエラーになるという事は、変数 a に格納してあるインスタンスが、
> 『VBDLL.clsVBDLL[] 型』のオブジェクトになっていない可能性があります。
> 
> あるいは、DLL のバイナリ互換性が失われたために、VB6 側の「clsVBDLL ユーザー定義型」と
> C# 側の「clsVBDLL 構造体」が不一致状態になっている可能性もあります。この場合は、
>  (1) DLL への参照設定を解除する。
>  (2) 相互運用機能アセンブリ(Interop.*.DLL)を削除する。
>  (3) クリーン操作後、DLL を再度参照設定する。
> のように、参照設定をやりなおすことで回復する可能性があります。
> 
> 
> >>>>> ((System.ComponentModel.ISupportInitialize)(objVBDll)).BeginInit();
>>尚、BeginInit();の行は、DLLの初期化の為に必要かと思い記述致しましたが、
>>objVBDLL = new vbDLL.clsVBDLL();行を実行した際に初期化メソッドが実行されることが分かりました
>>ので削除致しました。
> 実際にはそんなコードは記述されていなかった、という事でしょうか。
> 通常であれば、objVBDll を ISupportInitialize にキャストすることは
> できないはずなので、どうやって実装したのか少し混乱していました。
度々お手数をお掛けして申し訳ありません。
教えて頂いた点の修正を行い再度実行してみましたが結果は変わりませんでした。
以下が今回試してみました内容です。
@VB側Functionに戻り値の定義を追加し、DLLを再作成致しました。
Public Function xxxx(ByRef dData() as Type_Data) as Integer
ARegsvr32にてVBDLL.DLLをUnregistし、再作成したDLLのSystem32へのコピー後、
 Regsvr32にてVBDLL.DLLを再Regist。
BC#側ソリューションエクスプローラより
 (1) 参照設定下に表示されているVBDLLの削除
 (2) Interop.VBDLL.dllを全て削除
 (3) 再度、参照設定にVBDLL.DLLを追加
C変数aの記述を変更。
 Array a = DTTBL; → System.Array a = DTTBL;
DFunctionの呼び出し記述を変更。
 objVBDLL.xxxx(ref a); → short r = objVBDLL.xxxx(ref a);
Functionの呼び出し行にブレークポイントを設定して実行しますと、「ローカル」表示には
名前    値           型
+DTTBL   {VBDLL.Type_Data[10]}  VBDLL.Type_Data[]
+a     {VBDLL.Type_Data[10]}  System.Array {VBDLL.Type_Data[10]}
 r     0            short
と表示されています。
名前の左側に表示されている「+」をクリックしますと、配列の各要素に設定した値も表示
されます。
良さそうには見えますが実行しますと、
「パラメータが間違っています。(HRESULTからの例外:0x80070057 (E_INVALIDARG))」
になります。
なお、
((System.ComponentModel.ISupportInitialize)(objVBDll)).BeginInit();
行は記述は有りますが、コメントアウトしてあります。
曖昧な知識でいいかげんな記述をしてしまい、恥ずかしく思います。
余計な混乱を招いたようで申し訳ありません。




返信 編集キー/


管理者用

- Child Tree -