【问题标题】:How to write modules on Windows?如何在 Windows 上编写模块?
【发布时间】:2011-09-04 06:51:51
【问题描述】:

我目前正在编写一个可以在 Windows 和 Linux 上运行的程序。该程序使用动态模块(LoadLibrary/dlopen)来简化不同功能的部署。

Linux 部分工作得很好:主程序使用 -Wl,--export-dynamic 导出函数和变量,以便模块可以访问它们,并且可以使用 gcc 的 -shared 选项编译模块,而无需解析所有链接时的符号依赖关系。

对于 Windows(使用 MSVC 2010),这似乎不起作用。我正在使用 __declspec(dllimport) 从主程序中导出函数和变量,但我无法从主程序中访问函数和变量,因为链接失败(未解析的外部,LNK1120)。

如何处理?谢谢。

编辑(代码示例):

核心文件.cpp

#include "core-file.hpp"

Cls_A cls_instance;

void Cls_A::do_something() {
    while(0);
}

核心文件.hpp

#ifdef TEST_EXPORTS
#define TEST_API __declspec(dllexport)
#else
#define TEST_API __declspec(dllimport)
#endif

class TEST_API Cls_A {
public:
    void do_something();
};

extern Cls_A cls_instance;

module.cpp

#include "core-file.hpp"

TEST_API int my_init_function() {
    cls_instance.do_something();
    return 0;
}

【问题讨论】:

  • 请发布出现问题的代码。您的某些陈述没有多大意义(例如“我正在导出函数...使用__declspec(dllimport);”您的意思是dllexport吗?您的意思是您正在导入函数吗?)。
  • 一个 DLL 有一个 LibMain。您是否在 VS 2010 项目的配置属性中设置了正确的配置类型?
  • 当您已经在 Linux 上使用 GCC 时,为什么还要在 Windows 上使用 MSVC?在所有平台上都使用 GCC,这将使您的工作更轻松,问题更少。

标签: c++ visual-studio module


【解决方案1】:

__declspec(dllimport) 用于编译使用 DLL 的程序。当你编译实际的 DLL 时,你想使用__declspec(dllexport)。

您对这些的使用必须一致。典型的习惯用法是定义一个宏,该宏将根据宏的存在来使用 dllimport 和 dllexport。在构建DLL的项目中,您定义宏意味着导出函数,而在其他项目中您没有定义它,意味着导入它们:

#ifdef PROJECT_NAME_BUILD_DLL
  #define DLL_SYMBOL __declspec(dllexport)
#else //PROJECT_NAME_BUILD_DLL
  #define DLL_SYMBOL __declspec(dllimport)
#endif //PROJECT_NAME_BUILD_DLL

DLL_SYMBOL void SomeFunction(Type value);

构建DLL的项目将定义PROJECT_NAME_BUILD_DLL; 使用包含这个头文件的 DLL 的项目没有定义这个。

【讨论】:

    【解决方案2】:

    在 Windows 上,当您要链接导出的符号时,您必须记住指定在链接要导入其符号的模块时生成的所有导入库。 (您可以在 Linux 上保留未解析的符号,因为可执行格式不同,并且可以将符号解析推迟到加载时间。)

    【讨论】:

    • 这是我记得的——所以即使在 Windows 上使用 gcc,这也是不可能的。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2013-02-04
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-16
    • 2021-11-17
    • 2012-06-21
    相关资源
    最近更新 更多