0

次のページのチュートリアルに従って C++ DLL を作成し、System32 フォルダーに配置しました: http://msdn.microsoft.com/en-us/library/ms235636%28v=vs.80%29。 aspx。PC のどこからでも .exe を実行できます。ここで、VB.NET アプリケーションから Add を呼び出せるようにしたいので、次のコードを追加しました。

Imports System.Runtime.InteropServices

Public Class Form1

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Try
            Dim Test As Integer
            Test = Add(1, 1)
            MsgBox(Test)
        Catch ex As Exception

        End Try
    End Sub

    <DllImport("MathFuncsDll.dll", EntryPoint:="Add", SetLastError:=True, CharSet:=CharSet.Ansi)> _
    Private Shared Function Add(ByVal a As Double, ByVal B As Double) As Double
    End Function

End Class

次のエラーが表示されます: DLL 'MathFuncsDll.dll で 'Add' という名前のエントリ ポイントが見つかりません。これは名前空間が原因だと思います。私はこれを調査しましたが、一部の Web ページでは、Platform Invoke では名前空間が許可されていないと述べており、一部の Web ページでは許可されていると述べられています。何が問題ですか?

4

2 に答える 2

3

エントリ ポイントの名前は「追加」ではありません。Visual Studio コマンド プロンプトから実行dumpbin /exports MathFuncsDll.dllして、エクスポートされた名前を確認します。この宣言を取得するには:

<DllImport("MathFuncsDll.dll", EntryPoint:="?Add@MyMathFuncs@MathFuncs@@SANNN@Z", _
           CallingConvention:=CallingConvention.Cdecl)> _
Private Shared Function Add(ByVal a As Double, ByVal B As Double) As Double
End Function

奇妙に見える名前は、「名前の装飾」と呼ばれる機能である C++ コンパイラによって生成されます。関数のオーバーロードをサポートしています。extern "C"関数宣言の前に置いて、それを抑制することができます。むしろしないほうがいいです。また、SetLastError が正しくないことにも注意してください。コードは実際には SetLastError() を呼び出してエラーを報告しません。また、CharSet は適切ではありませんでした。これらの関数は文字列を取りません。

Divide 関数についても何かを行う必要があります。C++ 例外をスローしても、相互運用シナリオではうまくいきません。例外をキャッチできるのは C++ コードだけです。

于 2012-10-14T18:13:54.310 に答える
0

名前空間は許可されていません。PInvoke はプレーンな C クライアントのように機能します。C++ の名前マングリングを防ぐために、MathFuncsDll を extern "C" として宣言することも忘れないでください。Dependency Walker または dumpbin を使用して、MathFuncsDll からエクスポートされた関数のリストを表示します。

于 2012-10-14T17:43:01.663 に答える