2012-10-14 55 views
0

我已經按照下面的頁面上的教程來創建一個c + + DLL,我已經把它放在System32文件夾中:http://msdn.microsoft.com/en-us/library/ms235636%28v=vs.80%29.aspx。我可以在PC上的任何地方運行.exe。現在,我希望能夠調用添加從VB.NET應用程序,所以我已經添加以下代碼:Visual C++託管應用程序:無法找到名爲「添加」的入口點

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。我相信這是因爲命名空間。我已經研究過這個,有些網頁說平臺調用不允許命名空間,有些網頁說它們是允許的。問題是什麼?

回答

3

入口點未命名爲「添加」。從Visual Studio命令提示符運行dumpbin /exports MathFuncsDll.dll以查看導出的名稱。要獲得此聲明:

<DllImport("MathFuncsDll.dll", EntryPoint:="[email protected]@[email protected]@[email protected]", _ 
      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++代碼可以捕獲異常。

+0

謝謝。 +1用於引用dumpbin.exe。我已經完成了你的建議,現在的錯誤是:「WindowsApplication1.Form1 :: Add'已經失去了堆棧,這可能是因爲託管的PInvoke簽名與非託管目標籤名不匹配,請檢查調用約定和參數PInvoke「 – w0051977

+0

幾乎在那裏,調用約定不是__stdcall。發佈更正。 –

+0

感謝您的糾正。 – w0051977

0

命名空間是不允許的。 PInvoke像普通的C客戶端一樣工作。不要忘記將MathFuncsDll聲明爲extern「C」,以防止C++名稱變形。使用Dependency Walker或dumpbin查看從MathFuncsDll導出的函數列表。

+0

感謝您的回答,但請看Hans Passant的回答。看起來可以使用命名空間。 – w0051977

+0

當然,如果您在PInvoke聲明中使用裝飾名稱。經典的方法是使用extern「C」,這看起來更好。裝飾名稱主要用於PInvoke,當我們需要使用沒有源代碼的第三方庫時,它會導出C++函數。 –

相關問題