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 包含到您的项目中。

您可以通过以下方式调用:
    Lo​​adLibrary("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)的思考

链接到 Visual Studio 动态库

如何使用 gcc 和 Visual Studio 的“静态链接”和“动态链接”构建 C/C++ 程序?

Visual Studio中怎么生成动态链接库的lib文件

动态链接库在编译时不生成 .lib 文件(Visual Studio C++ Express)

Visual Studio 2010 建立了一个动态链接库,运行时提示无法启动dll