gpt4 book ai didi

c - Windows 上带有 DLL 的动态模块

转载 作者:可可西里 更新时间:2023-11-01 09:22:31 25 4
gpt4 key购买 nike

我正在用 C 编写一个应用程序,它可以在运行时通过模块/共享对象/DLL 进行扩展。这些模块可能会使用现有程序的 API,但也可能会提供新功能供以后加载的模块使用,因此模块之间存在相互依赖的可能性。

我目前在 Linux 下的做法是让每个模块都定义一个 depends() 函数,该函数返回它所依赖的其他模块名称的列表。这样,我就可以自行编译和链接每个模块,使用 dlopen() 和 RTLD_LAZY 加载模块,首先解决其依赖关系,然后使用 RTLD_GLOBAL 完全加载它。这工作得很好并且完全符合我的要求。它还允许我用不同版本替换一个模块,而无需重新编译依赖它的所有其他模块。

将其移植到 Windows 时会出现实际问题。首先,我还没有找到任何方法来链接 DLL,除非已经为其提供所有依赖项的导出符号表。有没有我忽略的?

其次,Windows API 中的 LoadLibraryEx 似乎无法执行任何延迟加载,因为它没有让我处理依赖项,而是继续并在返回之前自行加载所有引用的 DLL。因为我想在将来实际加载模块之前也执行版本检查,所以这根本不是我想要的。有什么办法可以避免这种行为?

第三个奇怪的事情是,如果不重新编译依赖它的所有其他模块,我就无法替换 DLL。它有时确实有效,但通常会发生疯狂的事情或程序段错误。

甚至可以在 Windows 上编写这样的模块化应用程序吗?非常感谢任何建议或不同的方法!

更新:只是为了澄清我的模块如何在 Linux 上使用彼此的功能(我希望在 Windows 上也有):每个模块只返回另一个模块的名称想从所描述的 depends() 函数中调用函数并包含其 header ,然后直接在代码中调用使用的函数而不进行任何包装。这是可行的,因为 Linux 不要求您在链接时为共享对象解析所有符号。

最佳答案

您可以手动导出所有函数(使用 __declspec(dllexport))并使用 GetProcAddress 加载它们。在这种情况下,您需要知道每个函数的签名,并且仅限于 C 函数,但这是可行的。如果你编译这两个模块,你的 C 函数也可以返回 C++ 类,稍后会详细介绍。使用 GetProcAddressLoadLibrary 使模块完全独立。基本上,您需要手动进行链接,但据我了解,这就是您在 Linux 上所做的,对吧?

LoadLibary 仅加载库所依赖的库,因此请确保它们不会相互加载。它们要么是真正独立的,要么不是,如果处理得当,更改一个库不会强制重新编译另一个库(因为您没有将它们链接在一起)。

一个好主意是使用类似 COM 的东西,因此让您的每个库都返回一个接口(interface),而不是单独的函数。这样,您可以简单地加载整个 DLL 并将它们轻松链接在一起(传递 DLL -> 传递对象)。查查XPCOM和COM,其实很容易做到。

关于c - Windows 上带有 DLL 的动态模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1181991/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com