【问题标题】:Using __declspec(dllexport) instead of -EXPORT:使用 __declspec(dllexport) 代替 -EXPORT:
【发布时间】:2016-03-25 17:43:00
【问题描述】:

我正在查看导出函数的文档,它指出 __declspec(dllexport) 应该在命令行版本 -EXPORT: 之前使用:如果可能的话。我目前正在使用命令行变体。在尝试进行这些更改时,我试图了解正确的实现,但我遇到了问题。

DLL 的头文件:

#ifdef LIBRARY_EXPORTS
#define LIBRARY_API __declspec(dllexport)
#else
#define LIBRARY_API __declspec(dllimport)
#endif

#define PRINT_TEST(name) LIBRARY_API void name()
typedef PRINT_TEST(print_log);
// ^ What's the C++11 equivalent with the using keyword?

DLL 的源文件:

PRINT_TEST(PrintTest) {
    std::cout << "Testing DLL" << std::endl;
}

应用程序的源文件:

print_test* printTest = reinterpret_cast<print_test*>(GetProcAddress(testDLL, "PrintTest"));

问题是因为 __declspec(dllexport) 包含在 typedef 中吗?因此应用程序源文件中的语句实际上是:

__declspec(dllexport) void (*print_test)() printTest = reinterpret_cast<print_test*>(GetProcAddress(testDLL, "PrintTest"));

我没有收到任何编译器错误或警告。

【问题讨论】:

  • 我有一个问题,你为什么要从 .dll 动态获取你的函数,而不是包含 .dlls 头文件,并链接到 .dlls lib 文件?
  • 很难猜测 LIBRARY_API 可能是什么。使用 /EXPORT 链接器选项是从 DLL 导出标识符的一种方法。这是最痛苦的做法。下一个不那么痛苦的方法是使用 .def 文件。到目前为止,最简单的方法是在源代码中应用 __declspec(dllexport) 属性。任你选,认为最简单的方法是最简单的。
  • 你有什么问题? GetProcAddress 返回 NULL?
  • @AlgirdasPreidžius 我正在测试运行时编译的 C++。
  • @1201ProgramAlarm 是的,这正是它返回的内容。因此,我不确定我是否以正确的方式使用 _declspec(dllexport)。

标签: c++ windows visual-c++ dll


【解决方案1】:

问题是因为您要导出一个名称混乱的 C++ 函数。您要么需要将损坏的名称传递给 GetProcAddress(从不好玩),要么需要在函数声明中使用 __stdcall 来取消导出

LIBRARY_API __stdcall void PrintTest

extern "C"__stdcall 更简单,并将调用约定从 C++ 样式更改为 C 样式。 (这可能需要将“_PrintTest”传递给 GetProcAddress,因为 C 函数名称是如何导出的。)

【讨论】:

  • 非常感谢。名字修饰是个问题。我正在查看地图文件,这些都是生成的函数签名吗?如果函数名和参数从不改变,是否保证相同?
  • @Kookehs 在这两个问题上都正确。损坏的名称在映射文件中列出,除非参数类型或返回类型发生变化,否则损坏的名称不会更改。
猜你喜欢
  • 2018-08-05
  • 2012-07-14
  • 2023-01-26
  • 2015-02-24
  • 1970-01-01
  • 2020-01-28
  • 2016-02-13
  • 1970-01-01
  • 2011-11-23
相关资源
最近更新 更多