C++ DLL - 打破循环依赖项
C++ DLLs - breaking a circular dependency
我正在努力重构一个 5.5k 行的 DLL C++,将其拆分为许多较小的 DLL。 不幸的是,很多代码都是捆绑在一起的,在拆分 GiantDLL 的过程中,我引入了几个循环引用。
更具体地说,
//In emergeOSLib.h:
DLL_EXPORT std::wstring ELGetProcessIDApp(DWORD processID, bool fullName);
//In a couple of functions in emergeOSLib.cpp:
ELMessageBox(GetDesktopWindow(), messageText, (WCHAR*)TEXT("Emerge Desktop"), ELMB_OK|ELMB_ICONERROR|ELMB_MODAL);
//In emergeUtilityLib.h:
DLL_EXPORT int ELMessageBox(HWND hwnd, std::wstring messageText, std::wstring messageTitle, DWORD msgFlags);
//In a function in emergeUtilityLib.cpp:
out << ELGetProcessIDApp(GetCurrentProcessId(), false) << TEXT(": ") << debugText << std::endl;
瞧,一个循环参考。我很确定还有更多,这只是我现在正在处理的问题。
我做了一些研究,发现前向声明似乎是要走的路:
解析标头包含循环依赖项
C++中的循环依赖
第二个链接甚至表明前向声明比#include
更可取。
我现在有两个问题。首先,如何向前声明另一个 DLL 中的函数?我的理解是编译器仍然无法找到前向声明的函数(因为它没有将第二个 DLL 编译为第一个 DLL 的一部分)并且会抱怨。其次,哪个通常被认为是更好的做法,#include
声明还是前瞻性声明?
前向声明与#include
只有助于声明循环。 但是你有定义循环性。 如果您将所有定义链接在一起,多通道链接器将解决此问题......但你不是。
基本上有两种方法可以做到这一点。 首先,您可以将ELGetProcessIDApp
更改为实用程序库中的函数指针。 最初,它指向实用程序库中的某个存根值,当操作系统支持库加载时,它会使用特定于操作系统的实现覆盖该函数指针。
或者,可以使用链接器定义文件在 DLL 实际存在之前生成导入库。 这将通过创建一组循环依赖的 DLL 来解决链接器问题。 它可以工作,但它也可能导致令人惊讶的加载顺序效应,并表现出全局初始化排序惨败。
或者,只使用单个 DLL,并将重构限制为拆分源文件。
如何向前声明另一个 DLL 中的函数?
你不,它不起作用。您可以声明它,但链接阶段将失败。
相反,让 DLL A 正常链接到 DLL B,DLL B 在运行时从 DLL A 接收函数指针(或具有虚拟函数的对象)。
- C++GTKMM gui循环依赖关系
- 如何在头文件中声明类模板(由于循环依赖关系)
- 如何在具有循环依赖的类中dynamic_cast?
- C++模板方法中的循环依赖关系
- 修复循环依赖项 c++17 标头
- 涉及全局对象的循环依赖C++
- 循环依赖,在继承类的情况下使用覆盖方法
- Wt::D bo 中的循环依赖关系
- 在包含窗口标头时难以解决循环依赖关系问题
- 解决循环依赖关系 c++ 的想法
- C++循环依赖关系,未声明的标识符
- C++ 中的循环依赖关系问题
- 错误 C2512 视觉C++(并且不是循环依赖项)
- CMake 外部和内部静态库的循环依赖关系
- 正在从继承中解析循环依赖项
- "std::shared_ptr"循环依赖关系是如何导致问题的
- 纯引用而不是weak_ptr来打破循环依赖关系
- "invalid use of incomplete type" .解决循环依赖关系
- 如何避免模板方法的循环依赖
- 循环依赖结构,使用前向声明时结构的错误重定义