【问题标题】:Dynamic linking in Visual StudioVisual 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 方法?我不知道在哪里指定它的文件名

【问题讨论】:

    标签: c++ c visual-studio dll compilation


    【解决方案1】:

    您可能还需要将一个 .lib 文件添加到编译器的链接器输入中。检查您正在使用的库的文档。

    【讨论】:

      【解决方案2】:

      尝试使用 Win32 API 的 LoadLibrary 函数,以下链接可能会有所帮助:example

      【讨论】:

        【解决方案3】:
        1. 如果您的应用程序需要能够在没有 OpenSSL 的情况下运行,请使用 explicit run-time linking 的动态链接并处理不存在 DLL 的情况(例如,通过更改应用程序的行为/切换到其他库)。 我最近发现了一个很好的例子:
        2. 如果您的应用程序只能在环境中存在 OpenSSL(或您提供 DLL)时运行,请使用隐式运行时链接。
          对于 MSVC,最简单的方法是在源代码中添加 #pragma comment(lib,"libeay32.lib")(您可能需要使用相同的编译器生成 .lib 存根)
        3. 如果您的应用程序需要独立于环境。静态链接 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 包含到您的项目中。

          • 您可以通过以下方式调用:
            1. Lo​​adLibrary("libeay32.dll"); /* 语法:*/
            2. 声明一个指向要调用的函数的函数指针。

          例如。

          让你的 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;
                  } 
             }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-03-22
            • 1970-01-01
            • 1970-01-01
            • 2011-06-15
            • 2018-08-09
            相关资源
            最近更新 更多