如何从 Visual Basic 2010 调用 C++ dll 文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9632713/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:06:04  来源:igfitidea点击:

How to call a C++ dll file from Visual Basic 2010

c++vb.netvisual-studiodll

提问by GnomeDePlume

I'm using Microsoft Visual Studio 2010 Express: the C++ and VB versions.

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

  • There is some VB code that forms the body of a program, and all the GUI.
  • There is also some C++ code that does some fast processing (lots of loops).
  • 有一些 VB 代码构成了程序的主体,以及所有的 GUI。
  • 还有一些 C++ 代码可以进行一些快速处理(大量循环)。

I am trying to call the C++ code, compiled as a dll, using:

我正在尝试使用以下方法调用编译为 dll 的 C++ 代码:

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

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



And at the moment keep getting the error:

目前不断收到错误消息:

Unhandled exception has occurred in your application. Unable to find an entry point named 'CalcGraph' in DLL 'Model.dll'

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

Could someone explain how to correctly call the DLL, please?
Do you need any other information to better understand the problem?

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

I'm fairly new to programming, so please be patient with me!
That said, I'm prepared to do the leg-work, and have already spent quite a while reading around on this and other sites. Nothing seems to match quite well enough to help me understand what's going wrong.

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

回答by GnomeDePlume

Okay, with your help and a fair bit of Google, this finally works!

好的,在您的帮助和 Google 的帮助下,这终于奏效了!

Here's a run-down, in case it helps anyone else in the future:

这是一个破败,以防它在未来帮助其他人:

  • Use the Ultimate Header Filefor a blueprint of how to create the header file.
  • It is important to understand how compiling as C will not name mangle, whereas compiling as C++ will.
  • It also appears that DevC++ has a neat BUILDING_DLLflag but Visual Studio requires you to create a definition in your main.c file.
  • __stdcalldoes something called 'name decoration' that is different from name mangling but will still change your function name. Thanks to @slugonamission for giving me a pointer about this. It finally clicked when using dumpbin.exe, as suggested by @HansPassant.
  • so, switching to __cdeclmanages to avoid name decoration, and compiling in C (or using externand compiling in C++) avoids name mangling.
  • and the dll will finally give me CalcGraph as a valid entry point!
  • 使用Ultimate Header File获取如何创建头文件的蓝图。
  • 重要的是要了解如何编译为 C 不会命名 mangle,而编译为 C++ 会。
  • DevC++ 似乎也有一个整洁的BUILDING_DLL标志,但 Visual Studio 要求您在 main.c 文件中创建一个定义。
  • __stdcall执行与名称修改不同的名为“名称修饰”的操作,但仍会更改您的函数名称。感谢@slugonamission 给我一个关于这个的指针。正如@HansPassant 所建议的那样,它最终在使用 dumpbin.exe 时点击了。
  • 因此,切换到__cdecl管理以避免名称修饰,并且在 C 中编译(或extern在 C++ 中使用和编译)避免了名称修饰。
  • 并且 dll 最终会给我 CalcGraph 作为一个有效的入口点!

The Implicit / Explicit dll linking is a very important distinction. Implicit linking requires a .lib file, the .dll and perhaps also a .h file. Explicit linking is what I was after - you can get away with the .dll by itsself. Thanks to @squelos for the link explaining this.

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

And last but not least:

最后但并非最不重要:

In the dll:

在 dll 中:

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

And in the VB code:

在 VB 代码中:

Imports System.Runtime.InteropServices

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

And it finally worked!

它终于奏效了!

回答by slugonamission

I'm going to assume here the C++ DLL is written in pure C++ (not C++/CLI or anything like that). It seems that the VB Libkeyword will only be importing a .NET procedure, rather than a native procedure. Instead, you need to use P/Invoke.

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

Something like this may work

像这样的事情可能会奏效

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

But of course, fill in your parameters and return types too.

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

回答by squelos

In some cases, depending on how the DLL was generated (ordinal or by name) you may have to use the DLL with GetProcAddress

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

This documentation here can give you a quick overview of how to use DLL's the oldschool way MSDN Linking overview

此处的文档可以让您快速了解如何使用 DLL 的老派方式MSDN 链接概述

And finally, DumpBincan you help you out a lot, by allowing you to inspect a DLL (pretty useful if you dont have the sources or documentation )

最后,DumpBin可以帮助您很多,允许您检查 DLL(如果您没有源或文档,这非常有用)