【问题标题】:How to call a C++ dll file from Visual Basic 2010如何从 Visual Basic 2010 调用 C++ dll 文件
【发布时间】:2012-03-09 10:43:46
【问题描述】:

我使用的是 Microsoft Visual Studio 2010 Express:C++ 和 VB 版本。

  • 有一些 VB 代码构成了程序的主体和所有的 GUI。
  • 还有一些 C++ 代码可以进行一些快速处理(大量循环)。

我正在尝试调用编译为 dll 的 C++ 代码,使用:

Private Declare Sub CalcGraph Lib "Model.dll" ()


目前不断收到错误:

您的应用程序中发生了未处理的异常。 在 DLL 'Model.dll' 中找不到名为 'CalcGraph' 的入口点

有人能解释一下如何正确调用 DLL 吗?
您是否需要任何其他信息来更好地理解问题?

我是编程新手,所以请耐心等待!
也就是说,我已经准备好做腿部工作了,并且已经花了很长时间在这个网站和其他网站上阅读。似乎没有什么匹配得足够好,可以帮助我理解出了什么问题。

【问题讨论】:

  • 在 DLL 上使用 Dumpbin.exe /exports 查看导出名称的样子。如果可能不是“CalcGraph”。或者没有导出。
  • @HansPassant 不幸的是,dumpbin.exe 似乎没有随 Visual Studio Express 一起提供。我不认为还有其他工具可以完成这项工作?
  • 您正试图用螺丝刀敲钉子。获取完整版。

标签: c++ vb.net visual-studio dll


【解决方案1】:

好的,在您的帮助和一些 Google 的帮助下,这终于成功了!

这是一个破败,以防将来对其他人有所帮助:

  • 使用Ultimate Header File 了解如何创建头文件的蓝图。
  • 重要的是要了解编译为 C 不会命名 mangle,而编译为 C++ 会命名。
  • DevC++ 似乎也有一个简洁的 BUILDING_DLL 标志,但 Visual Studio 要求您在 main.c 文件中创建一个定义。
  • __stdcall 做了一些名为“名称修饰”的事情,它与名称修饰不同,但仍会更改您的函数名称。感谢@slugonamission 给我一个关于这个的指针。正如@HansPassant 所建议的,在使用dumpbin.exe 时它终于点击了。
  • 因此,切换到 __cdecl 可以避免名称修饰,并且在 C 中编译(或使用 extern 并在 C++ 中编译)可以避免名称修饰。
  • 这个 dll 最终会给我 CalcGraph 作为一个有效的入口点!

隐式/显式 dll 链接是一个非常重要的区别。隐式链接需要一个 .lib 文件、一个 .dll 文件,也许还需要一个 .h 文件。显式链接是我所追求的——你可以自己摆脱 .dll。感谢@squelos 提供的链接解释这一点。

最后但同样重要的是:

在 dll 中:

extern _COMPILING_ void __cdecl CalcGraph(PanelParameters *, Calculations *);

而在VB代码中:

Imports System.Runtime.InteropServices

Private Declare Sub CalcGraph Lib "myDLL.dll" (ByRef params As Parameters, _
ByRef calcs As Calculations)

终于成功了!

【讨论】:

    【解决方案2】:

    我在这里假设 C++ DLL 是用纯 C++(不是 C++/CLI 或类似的东西)编写的。似乎 VB Lib 关键字只会导入 .NET 过程,而不是本机过程。相反,您需要使用P/Invoke

    这样的事情可能会奏效

    <DllImport("Model.dll")>
    Public Shared Function CalcGraph
    End Function
    

    当然,也要填写你的参数和返回类型。

    【讨论】:

    • 啊哈,看起来很有希望。不幸的是,我仍然无法修复“找不到入口点”错误。我的 C++ 代码的格式可能会导致问题吗? C++ 看起来像这样 DLLIMPORT void __stdcall CalcGraph(Parameters *params, Calculations *calcs) 。浏览网络还表明,something has happened to P/Invoke 介于 VS2008 和 VS2010 之间,这也可能导致问题。如果您有任何其他建议,请告诉我。在此期间我会继续修补......
    • 在那种情况下,我不确定。它可能是__stdcall(因为它以不同的方式破坏名称)。由于它是 C++,您可能还需要extern "C"
    • GnomeDePlume,嗯,我经常在 VS 2010 中使用 C# 解决方案(框架 4.0)中的 p/invoke,并且在 P/Invoking 时我没有遇到很多问题。话虽如此,我对VS2008的经验很少。但我真的看不出两个版本之间会发生什么变化。
    • @squelos 听起来好像default settings changed,它可能会导致代码混乱的一些问题。但我在这方面不是很有经验……从这里看,一切都像是个问题!很高兴听到您的经历更加积极。
    • 是的,一开始我也一样,真是一团糟。然后我说:好的,我将停止尝试猜测如何使用 Dll,并阅读一些有关 DLL 的文档,所以现在,它只会让事情变得容易得多。人们似乎忘记了 .dll 只是一个扩展名。它们可以以几种不同的方式制作,并以多种不同的方式使用 :) 但我并不是说您在这样做时不会遇到语法/参数错误。
    【解决方案3】:

    在某些情况下,根据 DLL 的生成方式(顺序或按名称),您可能必须将 DLL 与 GetProcAddress 一起使用

    这里的文档可以让您快速了解如何使用 DLL 的老式方式MSDN Linking overview

    最后,DumpBin 可以帮你检查一个 DLL(如果你没有源代码或文档,这非常有用)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-13
      • 1970-01-01
      • 2013-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多