【问题标题】:Using dllimport with Visual C++在 Visual C++ 中使用 dllimport
【发布时间】: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。

【问题讨论】:

    标签: c++ windows dllimport


    【解决方案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 SourceHow to generate an import library (LIB-file) from a DLL?

      或者,使用LoadLibraryGetrocAddress

      【讨论】:

      • 您提出的编译指示有另一个目的:它指示链接器将指定的静态库添加到链接中。它可以用来方便地与 DLL 导入库链接,而无需在链接器命令行上指定它——如果 OP 有的话。
      猜你喜欢
      • 2013-10-27
      • 1970-01-01
      • 2012-04-19
      • 1970-01-01
      • 2011-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多