在 Visual C++ 中使用 dllimport
Posted
技术标签:
【中文标题】在 Visual C++ 中使用 dllimport【英文标题】:Using dllimport with Visual C++ 【发布时间】:2014-11-17 05:26:08 【问题描述】:我已经有几年没有做过任何 Windows 编程了,我对如何使用 dllimport 有点生疏。我有一些类似的东西:
extern "C"
__declspec(dllimport) int myFunct();
int main()
cout<<myFunct();
我收到 2 个未解决的外部链接器错误和 /DELAYLOAD:myLib.dll 被忽略的警告,因为没有找到来自它的导入。 我在这里想念什么?我以为我可以将 DLL 添加到延迟加载路径中,链接器会考虑将其用于 dll 导入??
这是一个没有 .h 或 .lib 文件的第 3 方 DLL。
【问题讨论】:
【参考方案1】:如果你想在运行时链接DLL,你根本不需要导入符号。
只需声明一个函数指针类型,然后LoadLibrary()
/LoadLibraryEx()
,最后从GetProcAddress()
中检索函数指针。
示例(为简洁起见省略了错误处理):
typedef int (*MyFunct_t)();
auto myDLL = LoadLibrary("mydll.dll");
auto MyFunct = (MyFunct_t)GetProcAddress(myDLL, "MyFunct");
MyFunct();
(此代码仅用于展示一般程序,从未编译和测试过,可能包含拼写错误和语法错误,请随时编辑此帖子以修复它们)
【讨论】:
我最终这样做了,试图找出编译器/链接器选项毫无意义。【参考方案2】:我是这样做的:
1) 将文件 MyLibDll.h 添加到项目中
#pragma once
#if MYLIB_EXPORTS
#define MYLIB_API __declspec(dllexport)
#else
#define MYLIB_API __declspec(dllimport)
#endif
2) 在库头文件中使用它作为
#include "MyLibDll.h"
class MYLIB_API myClass
这可以与方法一起使用。
3) 在 .dll 项目中添加编译器选项/D MYLIB_EXPORTS
。
不确定这是否是最佳解决方案,但它对我有用。
【讨论】:
这是一个没有 .h 或 .lib 文件的第三方 dll。 @ventsyv 你用什么IDE/编译器? AFAIK,您至少需要一个 .lib 文件才能在 Visual Studio 中使用 extern .dll 。另外,在这种情况下,我的回答完全没有意义。 VisualStudio 2012。我不需要 .lib,我以前做过,但不记得链接器选项了。 @ventsyv - 如果这些是附加要求,那么您应该将它们添加到您的问题中。否则,Pavel 会回答您的问题。【参考方案3】:__declspec(dllimport)
告诉编译器导入了一个符号,但它不知道从哪里导入。要指定它,您需要链接 DLL 随附的导入库。如果你没有,你可以让链接器为你生成它by providing a definition file。
【讨论】:
我想我可以告诉编译器在运行时延迟加载它?我可以通过调用 LoadLibrary 以编程方式完成,但我认为有办法让编译器为我完成这项工作? @ventsyv,/DELAYLOAD
是链接器的选项,而不是编译器。使用 .def 文件和指定 /DELAYLOAD
之间没有冲突。【参考方案4】:
可以这样使用,dllimport,
extern "C"
__declspec(dllimport) int myFunct();
请记住,myFunct
应该是您定义的dllexport
。
【讨论】:
【参考方案5】:我收到 2 个未解决的外部链接器错误和 /DELAYLOAD:myLib.dll...的警告。
这是一个没有 .h 或 .lib 文件的第 3 方 DLL。
尝试将以下内容添加到您的源文件中:
#pragma comment(lib, "myLib")
extern int myFunct();
pragma comment 在目标文件中为库放置一个条目。第二个提供函数的声明。
在您的 cmets 中,您可能也在谈论 /INCLUDE (Force Symbol References)。您也可以使用pragma comment
将其放在源文件中。
如果需要,您可以创建一个导入库。请参阅How To Create Import Libraries Without .OBJs or Source 和How to generate an import library (LIB-file) from a DLL?。
或者,使用LoadLibrary 和GetrocAddress。
【讨论】:
您提出的编译指示有另一个目的:它指示链接器将指定的静态库添加到链接中。它可以用来方便地与 DLL 导入库链接,而无需在链接器命令行上指定它——如果 OP 有的话。以上是关于在 Visual C++ 中使用 dllimport的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Visual C++ 2010 中使用 C++ 库 [重复]
在 Visual Studio 2017 中使用 64 位 Visual C++ 工具集
为啥我们在 Visual Studio 2013 中引用 C++ 项目?
在 Visual C++ 2005 中开发的 Visual C++ 项目 - 在 Visual C++ 2010 中,打开菜单时调试断言失败,但发布模式有效,如何解决?