在 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 C++ 中使用 python

为啥我们在 Visual Studio 2013 中引用 C++ 项目?

在 Visual C++ 2005 中开发的 Visual C++ 项目 - 在 Visual C++ 2010 中,打开菜单时调试断言失败,但发布模式有效,如何解决?

如何在 Visual C++ 中使用开源 C 库