我已按照以下页面上的教程创建了一个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”的入口点。我相信这是因为命名空间。我研究了这个,有些网页说平台调用不允许使用名称空间,有些网页说它们是允许的。有什么问题?
答案 0 :(得分: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 ++代码才能捕获异常。
答案 1 :(得分:0)
不允许使用命名空间。 PInvoke就像普通的C客户端一样。不要忘记将MathFuncsDll声明为extern“C”以防止C ++名称损坏。使用Dependency Walker或dumpbin查看从MathFuncsDll导出的函数列表。