8

这是我的文件夹结构:

/
|
 -- program.cpp
 -- utility.h
 -- utility.cpp
|
 -- module/
    |
     -- utility.h
     -- utility.cpp

// Note that I have two files named utility.h and two named utility.cpp

在构建项目时,我收到一个链接错误(LNK2028:未解析的令牌等等......),说一些符号没有定义。我已经确认所有符号都已定义,并且所有声明的函数都有相应的定义。

我有一种感觉,在编译我的项目时,两个文件夹中的文件在输出文件utility.cpp夹中被编译成相同的文件。utility.obj结果,一个覆盖另一个。

  1. 这是预期的行为吗?
  2. 如何构建具有两个同名文件(尽管位于不同文件夹中)的 C++ 二进制文件?
4

6 回答 6

12

右键单击两个/任何一个 .cpp 文件 > properties> C/C++> Output Files> Object File Name> 设置自定义名称。MyFile.cpp例如,如果两个文件都在文件夹中命名A,另一个在文件夹中B,您可以将输出设置为AMyFileand BMyFile

或者,您也可以使用宏在对象名称前加上直接父文件夹名称(即使用$(IntDir)\$(SafeParentName)$(SafeInputName))。如果这还不够(例如,您有A/B/MyFile.cppand C/B/MyFile.cpp)并且您不介意将一些目标文件弄乱源代码树,您也可以使用$(InputDir)\which 将目标文件放在与源文件相同的文件夹中。

然后 cpp 文件将被编译成两个不同的目标文件。

请享用!

VS2010 的更新:VS2010中有更好的解决方案,在这里查看。感谢n1ck评论

顺便说一句,如果内容具有相同的名称,您是否使用不同的名称空间将它们分开?

namespace A { // in folder A
    class CMyFile {};
};

namespace B{ // in folder B
    class CMyFile {};
};

// client.cpp
#include "A/MyFile.h"
#include "B/MyFile.h"
int main() {
    A::CMyFile aMyFile;
    B::CMyFile bMyFile;
    return 0;
}

我不知道这是否重要,但对人类来说肯定更清楚:D

于 2010-02-17T15:27:00.943 回答
2

您可以尝试将另一个项目添加到您的解决方案中,该项目将从您的模块构建一个静态mudule.lib文件.cpp .h,然后将您的主项目与该库链接。它应该使 VS 在单独的目录中输出 .obj 文件,并且您应该能够毫无问题地链接。

于 2010-02-17T15:01:10.150 回答
1

你真的想要在同一个项目中有两个不同但同名的文件吗?

于 2010-02-17T15:03:25.860 回答
1

最简单的方法是根据源目录将冲突的 .objs 放入不同的子文件夹(我在 2003 和 2008 中使用过这种技术)。

例如:

对于 src\gui\utils.cpp 将“对象文件名”设置为“.\Debug\gui/”,对于 src\database\utils.cpp 将其设置为“.\Debug\database/”。

虽然我在发现冲突时手动执行此操作,但我可以想象编写一个脚本来更新每个 .cpp 文件(或仅用于冲突文件)的项目将是一项非常微不足道的任务。

于 2010-12-27T22:28:30.967 回答
0

也许库(静态或动态)会对您的案例有所帮助。但是,如果在可执行文件或其他库中存在任何同名的公共符号,您仍然会遇到问题。

于 2010-02-17T15:02:27.413 回答
0

我不知道 VS 编译链。

但是,每个 .cpp 首先被编译成一个 .obj 文件。链接步骤将它们合并在一起。

将所有 .obj 文件放在同一个目录中是很常见的。因此,正如您所猜测的,在编译第二个时,会删除第一个。因此在编译过程中缺少一些符号。

可能有一个选项(同样,我不使用 VS)将 .obj 保留在与 .cpp 文件相同的目录中。缺点是您的源代码树上有一些垃圾。

我个人的意见是重构。

于 2010-02-17T15:03:12.907 回答