Visual Studio 中的动态链接
Posted
技术标签:
【中文标题】Visual Studio 中的动态链接【英文标题】:Dynamic linking in Visual Studio 【发布时间】:2010-04-13 15:10:55 【问题描述】:我必须与 OpenSSL libeay32.dll 动态链接。 我正在使用 Visual C++ Express 2008 编写本机 C++ 控制台应用程序。
我包含来自 OpenSSL 发行版的标头 evp.h。建筑和...:
error LNK2001: unresolved external symbol _EVP_aes_256_cbc
error LNK2001: unresolved external symbol _EVP_DecryptInit
error LNK2001: unresolved external symbol _EVP_CIPHER_CTX_init
如何调用 libeay32.dll 方法?我不知道在哪里指定它的文件名
【问题讨论】:
【参考方案1】:您可能还需要将一个 .lib 文件添加到编译器的链接器输入中。检查您正在使用的库的文档。
【讨论】:
【参考方案2】:尝试使用 Win32 API 的 LoadLibrary 函数,以下链接可能会有所帮助:example
【讨论】:
【参考方案3】:-
如果您的应用程序需要能够在没有 OpenSSL 的情况下运行,请使用 explicit run-time linking 的动态链接并处理不存在 DLL 的情况(例如,通过更改应用程序的行为/切换到其他库)。
我最近发现了一个很好的例子:
Google Gears WinCE Geolocation API
itsutils
如果您的应用程序只能在环境中存在 OpenSSL(或您提供 DLL)时运行,请使用隐式运行时链接。
对于 MSVC,最简单的方法是在源代码中添加
#pragma comment(lib,"libeay32.lib")
(您可能需要使用相同的编译器生成 .lib 存根)
如果您的应用程序需要独立于环境。静态链接 OpenSSL(也使用 .lib)。
注意.lib
有两种。第一个用于动态但隐式链接,第二个用于静态链接。用于动态隐式链接的一个包含为您加载 DLL 的存根,而用于静态链接的一个包含实际实现。
【讨论】:
【参考方案4】:在项目属性、配置属性、链接器、输入-在“附加依赖项”下添加库名。
[注意,这实际上会与库进行静态链接。如果您真的想动态加载库,您需要在 DLL 上调用 LoadLibrary(),然后使用 GetProcAddress() 获取所需函数的函数指针。
参见示例
http://msdn.microsoft.com/en-us/library/ms886736.aspx
和
http://msdn.microsoft.com/en-us/library/ms885634.aspx
【讨论】:
这不是真正的静态链接......实际的符号查找并确保调用者指向被调用者仍然在运行时动态发生。 我还有两个问题可以吗? 1. 我的解决方案中有一个 dll 项目。要对其进行调用,我执行以下操作。右键单击我的 exe 项目 -> 属性 -> 通用属性 -> 框架和参考 -> 添加新参考 -> 在打开的窗口中我从列表中选择我的 dll 项目。重要的一点是它不是托管程序集。一切都是原生的。然后我在我的exe项目中包含一个头文件,构建并且一切正常......在这种情况下VS的行为如何?我可以以同样的方式链接到 libeay32.dll 吗?没有浏览到 dll 的选项... 2.使用 .lib 链接后,我可以简单地替换 libeay32.dll 来更新它。或者我将不得不链接我的项目?【参考方案5】:如果你从 dll 中调用方法,你可以使用显式动态链接方法。
错误:您将 OpenSSL 分发 dll 中的标头 evp.h 包含到您的项目中
您可以通过以下方式调用:当您动态链接时,无需将 .h 从 A DLL 包含到您的项目中。
-
LoadLibrary("libeay32.dll"); /* 语法:*/
声明一个指向要调用的函数的函数指针。
例如。
让你的 libeay32.dll 有一个导出函数:int add(int x, int y);
然后在你的项目中调用它,声明一个函数指针,然后调用方法add如下:
typedef int (*AddfnPtr)(int num1, int num2);
int num1 = 2, num2 = 3 ;
HMODULE handle = NULL;
handle = LoadLibrary("libeay32.dll");
if (handle != NULL)
AddfnPtr addfnptr = (AddfnPtr)GetProcAddr(handle, NULL);
if (addfnptr != NULL)
int res = addfnptr(num1,num2);
cout << "res = "<<res;
【讨论】:
以上是关于Visual Studio 中的动态链接的主要内容,如果未能解决你的问题,请参考以下文章
Visual Studio 2017 动态链接库(DLL /LIB) 静态链接库(LIB)的思考
如何使用 gcc 和 Visual Studio 的“静态链接”和“动态链接”构建 C/C++ 程序?