如何在Windows上编写模块

How to write modules on Windows?

本文关键字:模块 Windows      更新时间:2023-10-16

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

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

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

如何处理?谢谢你。

编辑(代码示例):

core-file.cpp

#include "core-file.hpp"
Cls_A cls_instance;
void Cls_A::do_something() {
    while(0);
}

core-file.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)用于在编译使用 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的项目不定义此。

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