• 締切済み

VB6で作成した自作DLLをVB.NETで呼び出し例外発生時に参照渡しの引数に値を設定する方法

VB6で作成した自作のDLLをVB.NET2005で作成したEXEから呼び出した際に、DLLメソッドの正常・異常終了に関わらず第2引数の戻り値に第1引数の値を設定したいと考えていますが旨くいきません。 何かよい方法はないでしょうか? 以下、簡単なサンプルです。 =========================== VB6 DLL =========================== Public Sub getDataForTest(ByVal strIn As String, ByRef strOut As String) Dim intData As Integer 'strInの値をstrOutに代入 strOut = strIn 'strInの値を1で割り算 intData = CInt(strIn) / 1 End Sub =============================================================== =================== DLL呼び出し正常パターン =================== Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim objCom As New Project1.Class1 Dim strRet As String = "" Try Call objCom.getDataForTest("1", strRet) Catch ex As Exception MsgBox(ex.Message) Finally MsgBox(strRet) ←←← 1が表示される  End Try End Sub =============================================================== =================== DLL呼び出し異常パターン =================== Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim objCom As New Project1.Class1 Dim strRet As String = "" Try Call objCom.getDataForTest("A", strRet) Catch ex As Exception MsgBox(ex.Message) Finally MsgBox(strRet) ←←← この時にAを表示したいがstrRetが空  End Try End Sub ===============================================================

みんなの回答

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.2

VB6のDLL側で エラートラップを仕込まないといけないみたいですよ Public Sub getDataForTest( ... )   Dim intData As Integer   'strInの値をstrOutに代入   strOut = strIn   ' エラートラップを設定   On Error Resume Next   'strInの値を1で割り算   intData = CInt(strIn) / 1   if Err.Number then     ' 何らかのエラー処理   end if   ' エラートラップを解除   On Error goto 0   ' 任意の処理 End Sub

amanda9310
質問者

お礼

回答ありがとうございます。 DLL側でエラーを無効にして、 EXE側で例外をキャッチしないようにすればいいわけですね。 参考にします。 出来れば、EXE側で何とか出来ればいいのですが。。。

noname#245936
noname#245936
回答No.1

VB.NETよく判りませんが。 確か、.NETはRefの戻り値はRef型で引数をあげないといけない ような気がします。 ちなみに。 .NET移行にかかわらずVB6のDLLを利用する価値がイマイチ見出せ ません。RegSvr32でエントリしないといけないし、VBランタイムも 必須ですし、処理のオーバヘッドもあると。 Distributionが簡潔になるのもまた.NETのウリですので。 DLLの.NET化を試したいところだと思います。

amanda9310
質問者

お礼

回答ありがとうございます。 同感です。 今回は、 提供されているDLLをそのまま使用しないといけないため、 仕方がないのですが、 今後の開発からは、その方向で検討していきたいと思います。

関連するQ&A

  • C++で作成したDLLを vb.net から動的に

    C++で作成したDLLを vb.net から動的に使用する方法 <DllImport("DllNAME")> _ Private Shared Function FuncName( _   <MarshalAs(UnmanagedType.LPStr)> ByVal str1 As StringBuilder, _   <MarshalAs(UnmanagedType.LPStr)> ByVal str2 As StringBuilder ) As String End Function Sub huga()   Dim result As String = FuncName( "hoge", "piyo" )   MsgBox(result) End Sub 上記方法で 静的にはリンク出来たのですが 動的にリンクする方法がわかりません ご教授ください お願いします!

  • OpenOffice.org Basicについて

     OOo.rcg Basicでsheet1のセルA2に入力されている文字列を指定されたバイト(桁)数にしたいんですが(今回は5バイトに指定し、桁数が足りない時はスペースで埋めます。)、メッセージボックスでは欲しい文字列が返ってくるのに、最後のセルへの代入ができません。  この説明文では理解できないかもしれませんが、おかしい所が分かる方教えていただけませんでしょうか? Function tkorigin(strVal As String, siteiketa As Integer) As String Dim moto As string Dim keta As long Dim i keta = len(strVal) moto = strVal if keta <> siteiketa then if keta < siteiketa then for i = 1 to siteiketa - keta moto = moto & " " next else moto = left(strval,siteiketa) end if end if ' msgbox "[" & moto & "]" tkorigin = moto End Function '--------------------------------------------------------------- Sub tameshi Dim strin As String Dim strout As String strin = Thiscomponent.Sheets(0).getCellByPosition(0,1).String strout = tkorigin(strin, 5) strin = strout ' msgbox "[" & strin & "]" End Sub

  • VB.netでDLLを読み込んで実行する際に、スタックを不安定にしていますというエラーが出ます。

    いつもお世話になります。 掲題の通り、VB.net上からDLLの関数を呼び出したいのですが、 「PInvoke 関数 がスタックを不安定にしています。PInvoke シグネチャがアンマネージ ターゲット シグネチャに一致していないことが原因として考えられます。呼び出し規約、および PInvoke シグネチャのパラメータがターゲットのアンマネージ シグネチャに一致していることを確認してください。」 というエラーメッセージが出力されます。 ソースコードは以下の通りです。 Public Class Form1 Private Declare Sub PrintShmLog Lib "XXXX.dll" (ByVal iTaskId As Long, _ ByVal iLevel As Long, _ ByVal pMsg As String) Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim iTskNo As Long = 1 Dim iLevel As Long = 0 Dim str As String = "★★★" Try Shell("XXXXXX.exe", vbHide) PrintShmLog(iTskNo, iLevel, str) Catch ex As Exception MessageBox.Show(ex.ToString) End Try End Sub End Class 原因を追いようが無くて困っています。 どなたかご存知の方がいらっしゃいましたらご教授ください。

  • VB.NETで値や参照について ByRefなど

    VB.NETで値や参照について、まだ初学ですがよろしくお願いします。 VBは2008です。 以下のようなs文字列を参照引数にしたSetDataメソッドがあります。 ByRef s As Stringという引数は、SetData内でsを書き換えると、 呼び出したSetDataメソッド外でも中身が変わるので 私のByRefの認識ではポインタと解釈しています。間違っているでしょうか? SetData(1,1, buf)とすれば、DataGridViewの中は、「初期値」という文字が表示されます。 別のメソッド(KaKikae)でbufを"あ"という文字に変えた場合、SetDataメソッドを使わなくても 書き換わっていると思っていたのですが、実際実行してみると書き換わりません。 値や参照について理解が足りないからだと思いますがわかりません。 どのようにすれば、それが実現できるのでしょうか? Public Class HogeClass Private buf As String = "初期値" Private Sub SetData(ByVal x As Integer, ByVal y As Integer, ByRef s As String) As Boolean Dim dg As DataGridView dg = DataGridView1 dg.Item(x, y).value = s End Sub Private Sub KaKikae() buf = "あ" End Sub End Class

  • VB.netでパスワード変更

    下記のようなパスワードを変更するフォームをVB.netで作成したのですが、 実行すると、いつも異なるretValの値がかえってきて変更できません。 retValの値もよくわからない大きな数値がかえってくるのでどのようなエラーかも 判断つかず。 どこが間違っているかお分かりになる方いらっしゃいますでしょうか。 Public Class Form1 Private Declare Function NetUserChangePassword Lib "netapi32.dll" (ByVal Domain As String, ByVal User As String, ByVal OldPass As String, ByVal NewPass As String) As Long Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim retVal As Long Dim sDomain As String Dim sUser As String Dim sOldPass As String Dim sNewPass As String sDomain = "xxxxxxx" ←ここはサーバのIPアドレス sUser = TextBox1.Text sOldPass = TextBox2.Text sNewPass = TextBox3.Text retVal = NetUserChangePassword(sDomain, sUser, sOldPass, sNewPass) MsgBox(retVal) End Sub End Class

  • C++製DLLにてVB.NET関数を引数付きでコールバックしたい。

    C++製DLLにてVB.NET関数を引数付きでコールバックしたい。 以下のようなソリューションがあります。 ソリューションには、VB.NETによるプロジェクトapp、C++によるプロジェクトdllがあり、 名前のとおり、appはWindowsフォームアプリケーション、dllはクラスライブラリです。 *** VisualStudio.NET 2003 ソリューション *** === VB.NETプロジェクト:app.exe === --- Module1.vb --- Module Module1 Delegate Function _t() As Int32 <System.Runtime.InteropServices.DllImport("dll.dll")> Public Function dllfunc(ByVal lpFunc As _t) As Int32 End Function End Module --- Form1.vb --- Public Class Form1 Inherits Form Private button1 As Button Public Sub New() button1 = New Button button1.Parent = Me : button1.Text = "button1" AddHandler button1.Click, AddressOf MyClass.GetEvent End Sub Private Sub GetEvent(ByVal sender As Object, ByVal e As EventArgs) dllfunc(AddressOf func1) End Sub Public Function func1() As Int32 MsgBox("func1@vb.net") Return 123 End Function End Class === C++ライブラリプロジェクト:dll.dll === --- dll.def --- LIBRARY dll EXPORTS dllfunc --- dll.h --- #ifdef DLL_EXPORTS #define DLL_API __declspec(dllexport) #else #define DLL_API __declspec(dllimport) #endif DLL_API void dllfunc(int* vbfunc(void)); -- dll.cpp --- #include "stdafx.h" #include "dll.h" #include "stdio.h" #include "windows.h" BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return true; } DLL_API void dllfunc(int* vbfunc(void)) { char str[16]; sprintf(str,"vbfunc() = %d",vbfunc()); MessageBoxA(NULL,str,"dll",MB_OK); } --- stdafx.cpp, stdafx.h --- (省略) *** ソリューション ここまで *** [ 動作 ] appを実行すると、Form1にbutton1が生成される。 button1をクリックするとGetEventが呼ばれ、func1のアドレスを引数としたdllfunc()を呼びます。 dll側のdllfunc()から、app側のfunc1()を呼び、戻り値の123を表示します。 [ 質問 ] dllfunc()から引数付きでfunc1()を呼びたいが、記述の方法が分かりません。 ご教示お願い致します。

  • null 参照の例外が実行時に発生する可能性があります

    VB初心者です。色々調べてみたのですが分からなくて、ヒントでも結構ですので教えていただけないでしょうか。 現在VB.Net2003 からVB2005に移行しているのですが下記の関数で現在開いているフォームを調べていますがVB.Net2003だとなんら問題なかったのにVB2005では「関数 'FormIsLord_Tag' は、すべてのコード パス上では値を返しません。結果が使用されるときに、null 参照の例外が実行時に発生する可能性があります。」という警告が出てしまいます Function FormIsLord_Tag(ByVal GetTag As String) As Form Dim LoopForm As Form Try For Each LoopForm In Forms If LoopForm.Tag = GetTag Then Return LoopForm End If Next Catch ex As Exception MessageBox.Show(ex.ToString) End Try End Function If LoopForm.Tag = GetTag Then とかの前にLoopFormがNothingだったらとか色々やってみましたがわからなくて・・・ 警告なので動かないって訳ではないのですが・・・ よろしくお願いします。

  • VB TEXT読み取りについて

    このコードでのデバックは成功したのですが、TEXTBOX1にファイルネーム C:\Users\???\Documents\???と入力しても’パスが拒否されました’と出てしまいます。 どう解決したらよいのでしょうか、宜しくお願いします。 Public Class Form1 Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim sr As System.IO.StreamReader = Nothing Try Dim file As String = TextBox1.Text sr = New System.IO.StreamReader(file, System.Text.Encoding.GetEncoding("shift_jis")) Dim doc As String = "" Do Until sr.EndOfStream doc &= sr.ReadLine & vdcrlf() Loop TextBox2.Text = doc Catch ex As Exception MessageBox.Show(ex.Message, "read") Finally If sr IsNot Nothing Then sr.Close() sr.Dispose() End If End Try End Sub Private Function vdcrlf() As String Throw New NotImplementedException End Function End Class

  • 構造体配列を引数とするDLL作成し、VBで呼ぶには?

    はじめまして。 VisualC++6.0でDLLを作り、VisualBasic6.0にて VisualC++の関数をコールし、構造体配列の値を 渡そうとしていますがうまくいきません。 どなたかよい知恵をお貸しください。 宜しくお願い致します。 下記に、VisualC++6.0とVisualBasic6.0のやりとり を記します。 *====Visual C++ 6.0側===== typedef struct _DLP_MSGDATA { int flg; char msg[504]; int tmp; } DLP_MSGDATA; _declspec(dllexport) int _stdcall SampSub(int data, DLP_MSGDATA *mdata) { return( 0 ); } *====Visual Basic 5.0側===== Declare Function SampSub Lib "test.dll" Alias "_SampSub@8" _ ( _ ByVal tlp_id As Long, _ ByRef mdata() As DLP_TLP_MSGDATA _ ) As Long Type DLP_TLP_MSGDATA flg As Long msg As String * 504 tmp As Long End Type Private Sub test() Dim mdata(0 To 130) As DLP_TLP_MSGDATA Dim aa As Long Call SampSub( aa, mdata ) End sub

  • VB.netでSQLserverに接続したい

    VB2008express で SQLserver2000に接続しようとしています フォーム上で ボタンを2つ作成し button1の記述では接続できるのですが button2では接続できず タイムオーバーになります。 SqlConnectionの使い方など基本的な理解不足かと思いますが お気づきの点あればお願いします。 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim DATACNN As String Dim DATAADO As ADODB.Connection DATACNN = "DRIVER={SQL SERVER};" & "SERVER=TESTSERVER;UID=sa;PWD=123;DATABASE=BD" DATAADO = New ADODB.Connection DATAADO.Open(DATACNN) MsgBox("接続1OK") End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim stConnectionString As String = String.Empty stConnectionString &= "Data Source =TESTSERVER;" stConnectionString &= "persist security info=True;" stConnectionString &= "Database=BD;" stConnectionString &= "user id=sa;" stConnectionString &= "password=123;"  Dim cSqlConnection As New System.Data.SqlClient.SqlConnection(stConnectionString) cSqlConnection.Open()  ’←タイムオーバーになります MsgBox("接続2OK") cSqlConnection.Close() cSqlConnection.Dispose() End Sub

専門家に質問してみよう