masat21です。
現在VB .netで作成したexeからVC++ 6.0で作成したDLLに含まれる関数を
コールした際、以下に示すエラーメッセージが表示されます。
(エラーメッセージ)
'System.NullReferenceExeption'のハンドルされていない例外が、
WindowsApplication1.exeで発生しました。
同時に以下に示す追加情報が表示されます。
(追加情報)
追加情報:オブジェクト参照がオブジェクト インスタンスに設定
されていません。
上記に示したエラーを対策する方法についてご教示願います。
VC++6.0側のファイルは、COM DLLなのでしょうか。
それとも、通常の(?)DLLなのでしょうか。
また、VB.NET側のソースは、どのような物なのでしょうか。
判断材料が少ないので、何とも言えませんが、m(_ _)m
おそらくは、VB.NETからの呼び出す部分のソースに問題があるのかと。
masat21です。
VC++6.0側のファイル(Environ.dll)は自分で作成したDLLです。
次に、詳細のVB.NET側ソースを以下に示します。
(1)Form1.vb
fnGetEnviron()
(2)Module1.vb
Declare Function fnGetEnviron Lib "Environ" _
Alias "?fnGetEnviron@@YAKXZ" () As Long
Module1.vbのソースでは、1行で記述してあります。
上記のみで判断材料が少ないときは、再度ご教示願います。
そのときは、指摘の内容とVC++6.0側のソースも記載する考えです。
気がついた点だけですが。
>(2)Module1.vb
> Declare Function fnGetEnviron Lib "Environ" _
> Alias "?fnGetEnviron@@YAKXZ" () As Long
ここで戻り値の型がLongになっていますがこれは合っていますか?
VB.NETではLongは64bit、Integerは32bitに変更されています。
VB6.0でのLongを意味しているならIntegerを指定して下さい。
>(1)Form1.vb
> fnGetEnviron()
>
fnGetEnviron関数はFunctionだから戻り値を返す変数が必要なんじゃないですか?
もしくはCallステートメントを書くか。
当方では、以下のコードが動作しましたが、そちらでは如何でしょうか?
'======== Form1.vb ========
Option Explicit On
Option Strict On
Public Class Form1
Inherits System.Windows.Forms.Form
#Region " Windows フォーム デザイナで生成されたコード "
' (中略)
#End Region
Private Sub Button1_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
MessageBox.Show(GetDesktopWindow().ToString("x"))
End Sub
End Class
'======== Module1.vb ========
Option Explicit On
Option Strict On
Module Module1
Friend Declare Function GetDesktopWindow Lib "USER32" () As Integer
End Module
もし、上記の「GetDesktopWindow」の部分を、自作のアンマネージDLLに
置き換えてみて動かないようであれば、そのDLLが StdCall規約に
なっているか否かを確認してみてください。
****別の書き方
'======== Module1.vb ========
Option Explicit On
Option Strict On
Module Module1
<System.Runtime.InteropServices.DllImport("USER32.DLL", _
EntryPoint:="GetDesktopWindow", _
CallingConvention:=System.Runtime.InteropServices.CallingConvention.StdCall)> _
Friend Function GetDesktopWindow() As Integer
End Function
End Module
>(エラーメッセージ)
> 'System.NullReferenceExeption'のハンドルされていない例外が、
> WindowsApplication1.exeで発生しました。
>(追加情報)
> 追加情報:オブジェクト参照がオブジェクト インスタンスに設定
> されていません。
エラーメッセージを見た限りでは、WindowsApplication1.exeでエラーが発生したということと、オブジェクト参照に関するエラーであることしか分からないのですが、Dll呼び出し以外を間違えているということはありませんか?
自分なんかは、たまにNewをし忘れてこのエラーが出ます。
一度トレースしてみてエラーの発生箇所を探してみてはいかがでしょうか?
もしくは、プログラムをそのまま投稿してみるのも良いかもしれません。
masat21です。
他の業務に従事していたため、回答が遅くなりました。
以下のように修正した結果、エラーメッセージは表示されなくなりましたが、
今度は、第2引数に環境変数PATHの内容が返されません。
原因についてご教示願います。(そのときのソースを以下に示します)
もちろん、環境変数PATHに設定されていることを確認しました。
それにしても、VB .netって奥が深いですね。
'======== Form1.vb ========
Option Explicit On
Option Strict On
Public Class Form1
Inherits System.Windows.Forms.Form
#Region " Windows フォーム デザイナで生成されたコード "
' (中略)
#End Region
Private Sub Button4_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button4.Click
Dim nRtn As Integer
Dim Buffer As String
Buffer = New String(CChar(" "), 1024)
Dim Size As Integer
Size = 1024
nRtn = GetEnvironmentVariable("PATH", Buffer, Size)
MsgBox(Buffer)
End Sub
End Class
'======== Module1.vb ========
Option Explicit On
Option Strict On
Module Module1
<System.Runtime.InteropServices.DllImport("kernel32", _
EntryPoint:="GetEnvironmentVariableA", _
CallingConvention:=System.Runtime.InteropServices.CallingConvention.StdCall)> _
Friend Function GetEnvironmentVariable(ByVal lpNmae As String, ByVal lpBuffer As String, ByVal nSize As Integer) As Integer
End Function
End Module
GetEnvironmentVariableの引数のうちポインタが必要な引数はありませんか?
もしあれば、ByValをByRefにしてみてください。
そういえば、これを間違えてオブジェクト参照に関するエラーが出た覚えがあります。
masat21です。
あれから、ソースを見直してから再度ロジックを通した結果、
環境変数の内容を表示することができました。
'======== Module1.vb ========
Declare Function GetEnvironmentVariable Lib "kernel32" _
Alias "GetEnvironmentVariableA" (ByVal lpName As String, _
ByVal lpBuffer As String, _
ByVal nSize As Integer) As Integer
'======== Form1.vb =========
<2つ前の内容と同じ>
いつも明確な説明をいただきありがとうございます。
以上