繁体   English   中英

C ++ DLL-打破循环依赖

[英]C++ DLLs - breaking a circular dependency

我正在重构一个5.5k行的C ++ DLL,将其拆分为多个较小的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语句还是前向声明?

前向声明vs #include仅有助于声明循环。 但是您具有定义圆度。 如果将所有定义链接在一起,则多通道链接程序将解决此问题,但不是。

基本上有两种方法可以做到这一点。 首先,您可以将ELGetProcessIDApp更改为实用程序库中的函数指针。 最初,它指向实用程序库中的某些存根值,并且在加载OS支持库时,它将使用特定于OS的实现覆盖该函数指针。

或者,您可以使用链接器定义文件在DLL实际存在之前构建导入库。 通过创建一组循环依赖的DLL,可以解决链接器问题。 它可以工作,但也可能导致令人惊讶的加载顺序效果,并显示全局初始化顺序失败。

或者,仅使用单个DLL,并将您的重构限制为拆分源文件。

我该如何向前声明另一个DLL中的函数?

你不,它不起作用。 您可以声明它,但是链接阶段将失败。

而是让DLL A通常与DLL B链接,并且DLL B在运行时从DLL A接收函数指针(或具有虚拟功能的对象)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM