使用预编译头重构项目中某些文件的依赖关系会导致链接器错误

时间:2009-07-07 15:20:42

标签: c++ linker visual-c++ precompiled-headers

我正在使用MSVC ++ 6来构建一个非常大的项目。此项目中的某些源文件与我们用于维护应用程序的小实用程序共享。以前,这个小实用程序需要链接来自主应用程序的许多库,并且还需要运行时的主应用程序的DLL。我的任务是删除这些依赖项,听起来非常简单......不幸的是,主应用程序中使用的预编译头文件给我带来了很多麻烦。

我首先重新设计了该实用程序中的所有文件,以明确包含他们需要的所有内容,然后我删除了PCH的#include指令(这删除了该实用程序的95%不必要的依赖项)。这非常适合编译实用程序。但是,现在编译主应用程序会让我错过有关缺少预编译头指令的错误。我认为“很棒,我只是有条件地包括PCH”。这似乎不起作用......我得到了“意外的#endif”,如上所述here。我的下一个想法是在主应用程序中为在utilty和主应用程序之间共享的三个源文件关闭PCH。这成功编译,但在链接期间我得到了一堆看起来像这样的错误:

tls7d.lib(tls707d.dll) : error LNK2005: "public: unsigned int __thiscall RWCString::length(void)const " (?length@RWCString@@QBEIXZ) already defined in stripledescypher.obj

AFAICT,所有多重定义的符号都是我明确包含在共享文件中的符号,以避免需要PCH。我的预感是因为我将这3个文件链接到与PCH .cpp文件相同的DLL中,所以它们在多个地方编译。有没有办法解决这个烂摊子?我会尝试任何事情......

1 个答案:

答案 0 :(得分:1)

当编译器在处理编译单元时找到符号X的定义时,它将为链接器创建一个提示:X就在这里!

两个源文件的编译,#include带有定义的标题(即不仅仅是声明)将导致两个定义相同符号的目标文件。链接器将找到一个多次定义的符号。

因此,您的stripledescypher目标文件似乎包含WCString::lenght()const方法的定义。这可能是由于函数体在类的标题或类似的东西中定义。