Visual Studio 2010 的奇怪“警告 LNK4042”

发布于 2024-09-18 10:02:31 字数 1404 浏览 4 评论 0原文

我刚刚被 Visual Studio 2010 (C++) 的一些重要警告狠狠地打了一顿。

编译给出以下输出:

1 Debug\is.obj :警告 LNK4042:多次指定对象;额外内容被忽略
1 Debug\make.obj :警告 LNK4042:多次指定对象;额外内容被忽略
1 Debug\view.obj :警告 LNK4042:多次指定对象;额外内容被忽略
1 Identity.obj:错误 LNK2019:无法解析的外部符号 void __cdecl test::identity::view(void) (?view@identity@test@@YAXXZ) 在函数 void __cdecl test::identity::identity(void) (?identity @0test@@YAXXZ)
1 Identity.obj:错误 LNK2019:无法解析的外部符号 void __cdecl test::identity::make(void) (?make@identity@test@@YAXXZ) 在函数 void __cdecl test 中引用::identity::identity(void) (?identity@0test@@YAXXZ)
1 range.obj:错误 LNK2019:无法解析的外部符号 void __cdecl test::range::is(void) (?is@range@test@@YAXXZ) 在函数 void __cdecl test 中引用::range::range(void) (?range@0test@@YAXXZ)

链接器错误总是很难调试...但是存在未解析的引用,所以我检查了...但来源是格式良好......最后它击中了我:

我的文件夹层次结构看起来像这样:

src/
  identity/
    is.cpp
    make.cpp
    view.cpp
  range/
    is.cpp
    make.cpp
    view.cpp

解决方案中的层次结构也是如此(我总是将其设置为模仿“真实”文件夹结构)。

诊断输出:

Debug\is.obj
Debug\make.obj
Debug\view.obj

伴随着一条警告,表明 .obj 已被传递给链接器两次,并且其中一次将被忽略。

不再搜索:Visual 已经整齐地展平了我的文件夹层次结构,因此无法整齐地编译源代码。

目前,我只是想重命名文件,这应该可以解决问题......

但是有没有办法让 Visual Studio 不展平文件层次结构?

I've just been beaten (rather hardly) on the head by some non-trivial warning from Visual Studio 2010 (C++).

The compilation gave the following output:

1 Debug\is.obj : warning LNK4042: object specified more than once; extras ignored
1 Debug\make.obj : warning LNK4042: object specified more than once; extras ignored
1 Debug\view.obj : warning LNK4042: object specified more than once; extras ignored
1 identity.obj : error LNK2019: unresolved external symbol void __cdecl
test::identity::view(void)
(?view@identity@test@@YAXXZ) referenced in function void __cdecl test::identity::identity(void) (?identity@0test@@YAXXZ)
1 identity.obj : error LNK2019: unresolved external symbol void __cdecl test::identity::make(void) (?make@identity@test@@YAXXZ) referenced in function void __cdecl test::identity::identity(void) (?identity@0test@@YAXXZ)
1 range.obj : error LNK2019: unresolved external symbol void __cdecl test::range::is(void) (?is@range@test@@YAXXZ) referenced in function void __cdecl test::range::range(void) (?range@0test@@YAXXZ)

Linker errors are always a pain to debug... but there were unresolved references, and so I checked... but the source is well-formed... and finally it hit me:

My folder hierarchy looks like so:

src/
  identity/
    is.cpp
    make.cpp
    view.cpp
  range/
    is.cpp
    make.cpp
    view.cpp

and so does the hierarchy in the Solution (I always set it up so that it mimicks the "real" folder structure).

And the diagnostic outputs:

Debug\is.obj
Debug\make.obj
Debug\view.obj

Along with a warning which says that the .obj has been passed twice to the linker and that one will be ignored.

Search no more: Visual has neatly flatten my folder hierarchy, and therefore is unable to neatly compile the source.

At the moment, I am simply thinking of renaming the files, that should cover the issue...

... but is there a way to have Visual Studio NOT flatten the file hierarchy ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

书间行客 2024-09-25 10:02:31

我有一个类似的问题,链接器警告LNK4042:多次指定对象;附加内容被忽略。就我而言,Visual Studio 尝试编译具有相同名称的头文件和源文件 - MyClass.hMyClass.cpp。发生这种情况是因为我将 .cpp 文件重命名为 .h 并且 Visual Studio 感到困惑。我通过查看 Debug 目录中的编译器日志注意到了这个问题。要解决此问题,只需从项目中删除 .h 文件,然后再次添加即可。

I had a similar problem with linker warning LNK4042: object specified more than once; extras ignored. In my case Visual Studio was trying to compile both header and source files with the same name - MyClass.h and MyClass.cpp. It happened because I renamed .cpp file to .h and Visual Studio got confused. I noticed the problem by looking at the compiler logs in the Debug directory. To resolve just remove .h file from the project then add it again.

謌踐踏愛綪 2024-09-25 10:02:31

只是想交叉发布我认为的答案,如果您打开整个项目的属性,并更改 C/C++ -> > 下的值。输出文件 -> “对象文件名”如下:

$(IntDir)/%(RelativeDir)/

在 VS 2010 下,我相信这将消除所有对象文件的歧义(因为我相信 Windows 不会让你在任何疯狂的情况是同一目录中有两个同名的文件)。另请查看详细信息 在这里

Just wanted to cross post what I believe to be the answer, if you open the properties for the entire project, and the change the value under C/C++ -> Output Files -> "Object File Name" to be the following:

$(IntDir)/%(RelativeDir)/

Under VS 2010, I believe this will disambiguate all of the object files (as I believe windows won't let you under any crazy circumstances have two files with the same names in the same directory). Please also check out the details here.

攒眉千度 2024-09-25 10:02:31

右键单击“解决方案资源管理器”窗口中的 .cpp 文件,依次选择“属性”、“C/C++”、“输出文件”、“对象文件名”设置。默认值为 $(IntDir)\,这就是进行扁平化的操作。所有 .obj 文件都将进入 $(IntDir),即调试配置中的“Debug”目录。

您可以更改设置,例如$(IntDir)\is2.obj。或者从一组中选择所有文件(使用 Shift+单击)并将设置更改为 $(IntDir)\identity\

或者您可以更改 .cpp 文件名,以便 .obj 文件不存在不要互相覆盖。在两个目录中拥有完全相同名称的文件有点奇怪。

或者,您可以创建多个项目,例如为标识和范围中的文件创建 .lib 项目。例如,通常在 makefile 项目中完成。然而,除非您使用项目属性表,否则这确实会使管理编译和链接设置变得更加麻烦。

Right-click the .cpp file in the Solution Explorer window, Properties, C/C++, Output Files, Object File Name setting. The default is $(IntDir)\, that's what is doing the flattening. All the .obj file will go into $(IntDir), the "Debug" directory in the debug configuration.

You can change the setting, say $(IntDir)\is2.obj. Or select all the files from one group (use Shift+Click) and change the setting to, say, $(IntDir)\identity\

Or you can change the .cpp filename so that .obj files don't overwrite each other. Having files with the exact same name in two directories is a bit odd.

Or you can create multiple projects, creating, say, .lib projects for the files in identity and range. Commonly done in makefile projects for example. That does however make managing the compile and link settings more of a hassle unless you use project property sheets.

烧了回忆取暖 2024-09-25 10:02:31

右键单击头文件->属性-> ItemType(选择C/C++ 标头)。对 Cpp 文件执行相同操作,但选择 C/C++ 编译器(这对我有用)

Right click on header file -> Property -> ItemType (select C/C++ Header). Do the same with Cpp file but select C/C++ Compiler (it's work for me)

摇划花蜜的午后 2024-09-25 10:02:31

除了删除并创建新文件之外,您还可以更改编译/包含设置。

转到您的 project.vcxproj 文件,使用编辑器打开它,找到类似 行的 html。

它应该类似于:

<ItemGroup>
<ClCompile Include="implementation.cpp" />
</ItemGroup>

<ItemGroup>
<ClInclude Include="declaration.hpp" />
</ItemGroup>`

假设您的实现文件是 .cpp,您的声明是 .hpp。如果您有多个声明文件,请确保您的所有实现文件都列在第一部分之间,对于多个声明文件,请确保在第二部分中列出。

Alternatively to deleting and making a new file you can change the compile/include settings.

Go to your project.vcxproj file, open it with an editor, find the html like line <ItemGroup>.

It should look something like:

<ItemGroup>
<ClCompile Include="implementation.cpp" />
</ItemGroup>

and

<ItemGroup>
<ClInclude Include="declaration.hpp" />
</ItemGroup>`

Assuming your implementation files are .cpp and your declarations are .hpp. Make sure your all your implementation files are listed between the first section if you have more then one and likewise for the second section for multiple declaration files.

爱格式化 2024-09-25 10:02:31

我在 stdafx.cpp 中遇到了这个问题。不知何故,stdafx.cpp 被重复,因此有第二个 StdAfx.cpp(注意不同的情况)。

删除 StdAfx.cpp 后,一切正常!

使用VS 2010。

I had this problem with stdafx.cpp. Somehow stdafx.cpp got duplicated, so there was a second StdAfx.cpp (mind the different case).

After I removed the StdAfx.cpp everything worked fine!

Using VS 2010.

半衾梦 2024-09-25 10:02:31

我在 C/C++ 下使用 $(IntDir)\%(Directory)\ ->输出文件 -> “对象文件名”。

I use $(IntDir)\%(Directory)\ under C/C++ -> Output Files -> "Object File Name".

∝单色的世界 2024-09-25 10:02:31

我曾经在同一个项目中拥有.c.cpp文件,它们具有相同的文件名。这些文件位于各处的文件夹中,其他人提供的解决方案造成了混乱,文件夹地狱(就我而言)。即使发布版本也会覆盖调试版本!

一个好的(不完美)解决方案是使用 $(ParentName),但由于某些超出任何人掌握的原因,它已从 Visual Studio 的更高版本(2015+)中删除。

我现在成功使用的是:
$(IntDir)%(Filename)%(Extension).obj

至少将 .c 构建的目标文件与 .cpp 分开。

I used to have in the same project .c and .cpp files with the same filenames. The files were in folders all over the place and the solutions provided by others created a mess, and folder hell (in my case). Even Release builds would overwrite Debug builds!

A good (not perfect) solution would be to use $(ParentName), but for some reason beyond anyone's grasp it has been removed from later versions of Visual Studio (2015+).

What I use succesfully now is:
$(IntDir)%(Filename)%(Extension).obj

which at least separates .c built object files from .cpp.

别低头,皇冠会掉 2024-09-25 10:02:31

我想指出 .h 文件ItemTypeC/C++ header 更改为 的一个可能原因>C/C++编译器

  1. 在VS的解决方案资源管理器窗口中(这里是2019),右键单击项目名称,选择添加->添加新项目
  2. 选择C++ File (.cpp)模板,但在名称输入区域中输入something.h,然后单击OK添加它;
  3. 如果 something.h 文件包含在多个 .cpp 文件中,您就会遇到 LNK4042 警告。

I'd like to point out one possible reason for why the ItemType of a .h file would change from C/C++ header to C/C++ compiler:

  1. In the Solution Explorer window of VS (2019 here), right click the project name, choose Add -> New Item;
  2. Select the C++ File (.cpp) template, but type something.h in the name input area, then click OK to add it;
  3. Then you'll encounter the LNK4042 warning if the something.h file be included within more than one .cpp files.
苍白女子 2024-09-25 10:02:31

我刚刚克服了类似的错误消息,并且通过以下过程解决了更多问题。症状:每次调用特定标头中定义的每个函数都会出现一个链接器错误,并且在标头中定义的每个函数的输出末尾都会出现一个链接器错误。

然后我记得当我最初创建此标头时,我不小心选择了“add->new item->c++ file”,虽然我将其命名为“whatever.h”,但由于我的操作不正确,Visual Studio 似乎将它们视为同一类型的文件。用于添加一个。检查构建输出日志使这一点显而易见。

解决方案(使用 VS Community 2019)

  1. 首先备份项目(为了安全起见)。
  2. 右键单击有问题的头文件并选择“从项目中排除”(这不会删除它们;VS 项目只会忽略它们)。
  3. 对匹配的 .c 或 .cpp 文件执行相同的操作。
  4. 在项目上执行构建 -> 清理
  5. 执行项目上的构建 -> 重建
    -- 当然会有错误---
  6. 右键头文件->添加->现有项,然后选择.h文件
  7. 右键单击​​源文件->添加->现有项,选择.c 或 .cpp 文件
  8. 在项目上执行“构建”->“重建”。

这完全为我清理了它,使我摆脱了许多恼人的链接器错误,包括这个问题标题中的 LNK4042。

I just overcame a similar error message, and lots more with the procedure below. Symptom: one linker error for every invocation of every function defined in a particular header, plus one at the end of output for every function defined in the header.

Then I remembered that when I had originally created this header, I accidentally had selected "add->new item->c++ file" and though I named it 'whatever.h', it seems Visual Studio considered them both the same kinds of files because of the incorrect action I used to add one. Examining the build output logs made this obvious.

SOLUTION (Using VS Community 2019)

  1. Back up project first (just to be safe).
  2. Right-click the offending header file and select "Exclude from project" (this will not delete them; the VS project will just ignore them).
  3. Do same for the matching .c or .cpp file.
  4. Do Build->Clean on project
  5. Do Build->Rebuild on project
    -- there of course will be errors---
  6. Right-click Header Files->Add->Existing Item, then select the .h file
  7. Right-click Source Files->Add->Existing Item, the select the .c or .cpp file
  8. Do Build->Rebuild on project.

This completely cleaned it up for me, relieving me of many irritating linker errors including LNK4042 from the title of this question.

成熟的代价 2024-09-25 10:02:31

我通过更改项目中的文件名解决了这个问题。有两个名为 main.c 和 main.cpp 的文件。我改变了其中之一并工作了。

I resolved it changing filenames in my project. There was two files named main.c and main.cpp. I changed one of them and worked.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文