我正在用 C 语言编写一个应用程序,它可以在运行时通过模块/共享对象/DLL 进行扩展。这些模块可能使用现有程序的 API,但也可能提供新功能供以后加载的模块使用,因此模块之间可能存在依赖关系。
我目前在 Linux 下的方法是让每个模块定义一个 depends() 函数,该函数返回它所依赖的其他模块名称的列表。这样,我可以自己编译和链接每个模块,使用 dlopen() 加载一个模块,RTLD_LAZY
然后首先解决它的依赖关系,然后使用RTLD_GLOBAL
. 这工作得很好,完全符合我的要求。它还允许我用不同的版本替换模块,而无需根据它重新编译所有其他模块。
将其移植到 Windows 时会出现实际问题。首先,我还没有找到任何方法来链接 DLL,而无需为其提供所有依赖项的导出符号表。有没有我忽略的?
其次,来自 Windows API 的 LoadLibraryEx 似乎无法执行任何延迟加载,因为它没有让我处理依赖项,而是在它返回之前自行加载所有引用的 DLL。由于我想在将来实际加载模块之前执行版本检查,这根本不是我想要的。有没有办法规避这种行为?
第三个奇怪的事情是,如果不重新编译依赖于它的所有其他模块,我就无法替换 DLL。它有时确实有效,但通常会发生一些疯狂的事情或程序段错误。
甚至可以在 Windows 上编写像这样的模块化应用程序吗?任何建议或不同的方法都非常感谢!
更新:只是为了澄清我的模块如何在 Linux 上使用彼此的函数(我也希望在 Windows 上也有):每个模块只返回它想从所描述的依赖中调用函数的另一个模块的名称() 函数并包含其头文件,然后直接在代码中调用使用的函数而无需任何包装。这是因为 Linux 不要求您在链接时为共享对象解析所有符号。