- ベストアンサー
VB6.0からVB.NETへの移行
VB6.0から.NETへの移行を行うこととなりましたが、C++で作成したDLL呼び出し方法がわからず悩んでいます。 C++側で作成したDLLは修正が出来ない為、.NET側のみで修正しなければならない状況です。 VB6.0側のプログラムは以下のような感じです。 Public FName() As String Declare Function A Lib "Test.dll" (ByRef field As Variant) As Long ReDim FName(4) As String FName(1) = "1" FName(2) = "22" FName(3) = "333" FName(4) = "4444" Call A(fieldName) C++側は、以下の形で受けているようです。 A(variant *field); SAFEARRAY *psa = *(field->pparray); VB.NET側で以下の様にしてみたのですが、まともに動いてくれません。 Public FName() As String Declare Function A Lib "Test.dll" (ByRef field As Object) As Integer ReDim FName(3) As String FName(0) = "1" FName(1) = "22" FName(2) = "333" FName(3) = "4444" Call A(FName) VB.NETに詳しい方であれば、すごく基本的なことなのではないかと思いますが、よろしくお願いいたします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
http://www7.big.or.jp/~pinball/discus/vb/60072.html なんか、こことすごく似ておりますが^^; 仮想でDLLを作成して、やってみました。 たしかにVB6からは問題ないですが、.netからはいろいろパターンをやってみましたが。問題なしでした。 一番のネックは >variant *field という部分ですね。 配列先頭のアドレスを渡してもみましたが、文字情報の先頭アドレスだけ渡り、そのアドレスが配列要素を持っているという認識が、C側で成されないようです。 DLLの宣言も様々やって見ましたが、配列情報が渡りませんでした。 Marshal.StructureToPtrメソッドなども利用してで、いろいろやってみましたが、これまた。。。。無理でした。。。 受け自体が、SAFEARRAYであれば、問題なしなのですが・・・ http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpguide/html/cpcondefaultmarshalingforarrays.asp 直接variantへのやりとりは、結構探したつもりですが、どこにもありませんでした。 無理なのかな~~~ 回避策でしかありませんが、Test.DLLのAを呼ぶためのDLLをCやVB6で作成し、ワンクッション処理をかませてはいかがでしょう?
その他の回答 (3)
- 1050 円(@1050YEN)
- ベストアンサー率69% (477/687)
#3の誤字と下記間違いを訂正いたします。 >たしかにVB6からは問題ないですが、.netからはいろいろパターンをやってみましたが。問題なしでした。 >たしかにVB6からは問題ないですが、.netからはいろいろパターンをやってみましたが、同様の処理を行ってくれませんでした。 m(_ _)m
- hawkwind
- ベストアンサー率34% (160/469)
マーシャリングは非常に厄介な問題ですね。 構造体の中にBSTR型がある場合は本気で勉強しなければいけないようです。 本件も文字型の配列になっていますから Cではこれをアドレスのアドレスと受け取っているかもしれません。 call a(Fname(0)) とかすればどうでしょう? 現在.netの開発環境でないので確信は全然持てません。 あしからず。
補足
ご回答ありがとうございます。 call a(Fname(0))でやってみましたが、うまく動きませんでした。 hawkwindさんのおっしゃる通り、マーシャリングの勉強を真剣にやらなければならないようです・・・。 hawkwindさんがご推薦するわかりやすい参考書、HP等があれば教えていただきたいのですがいかがでしょうか。 (やはりMSDNを真剣に読み解くのが一番なのでしょうか)
- hawkwind
- ベストアンサー率34% (160/469)
おはようございます。 このケースは実に多様です。 まずは基本に立ち返って環境、特にパスが正しいかどうか確認して下さい。 実行していたDLLの位置が実は違っていたというのはよくある話です。 デバッグ時にはDLLは1箇所においた方が間違いはおきません。 通常、このケースですとDLLに問題があることが多いようです。 まずはstdcall規約に沿っているか確認して下さい。 次に今まではまかり通っていたDLLの不具合が顕在化したかもしれません。 DLLのコンパイル時にワーニングが出ていたのであれば要注意です。
補足
朝早くからご回答ありがとうございます。 DLLについてですが、パスに関しては1箇所のみにおいています。 また、ワーニングも無いとのことでした。 色々と調べまして、C++側でSafearrayの形式で引数を受けているのですが、 .NETからStringの配列データをSafearray形式のByref型として引数で渡すか ご存知でしたらご教授いただけませんでしょうか。
お礼
しばらく悩んで、結局1050YENさんの提案していただいた ワンクッションかませる方法で対応しました。 どうもありがとうございました。
補足
丁寧なご回答ありがとうございます。 ごく基本的なことだと思っていたのですが、予想以上に厄介な事なのですね。 厄介な問題を色々と調べて頂いてすごく感謝しています。 もう少しがんばってみてだめならば、1050YENさんのアドバイスにもありますように 回避策を色々と検討してみようと思います。