“已在目标文件中定义”和“找到一个或多个多重定义的符号”
Posted
技术标签:
【中文标题】“已在目标文件中定义”和“找到一个或多个多重定义的符号”【英文标题】:"Already defined in object file" and "one or more multiply defined symbols found" 【发布时间】:2014-04-02 06:04:08 【问题描述】:通过MSDN 的 RPC 教程,
我刚刚创建了一个包含两个.c
文件的项目,如下所示::
/* file hellop.c */
#include <stdio.h>
#include <windows.h>
void HelloProc(char * pszString)
printf("%s\n", pszString);
return ;
和
/* file: hello.c */
#include "hellop.c"
void main(void)
char * pszString = "Hello, World";
HelloProc(pszString);
return ;
问题::错误LNK2005和致命错误LNK1169
编译器为什么以及在哪里看到HelloProc(char*)
的多个符号定义或声明?
编辑:: 正如SO_Question 中的结论,包括.h
文件显然是最好的解决方案。但这是否让我们无法实现设计,我们可以将.c
文件包含到另一个.c
文件中?
奇怪的行为:: 第一次编译运行良好,但解决方案的重建因上述错误而中断。您可以通过将文件名从.c
更改为.cpp
来检查多次首次编译,反之亦然。为什么它会表现出这种行为? (我不确定其他人是否也经历过给定示例)
【问题讨论】:
【参考方案1】:你编译了两次HelloProc
,因为你在hello.c
文件中包含了这个函数的整个定义#include "hellop.c"
,而你只需要声明它。你应该把函数原型放在头文件中。
#ifndef HELLOP_H
#define HELLOP_H
#include <stdio.h>
#include <windows.h>
void HelloProc(char * pszString);
#endif
并在hellop.c
和hello.c
中包含头文件
编辑:#include
不是你说的剪切粘贴,更像是复制粘贴
# 包含“q-char-sequence”换行符
导致该指令被整个内容替换 源文件由“之间的指定序列标识” 分隔符
这样您就可以与HelloProc
的两个定义联系起来,一个在hellop.c
中,另一个在hello.c
中。另一种解决方法是只编译hello.c
文件,这样就没有HelloProc
的重复。在 VisualStudio 中查看如何操作here
【讨论】:
感谢您的回答,但我认为这不是问题所在。另外,我没有任何“main.c”文件,它是“hello.c”:-)。再一次,我知道,将声明放在头文件中会很棒,但我想知道这背后的原因是什么。 “#include”就像剪切粘贴的东西(粗略地说),那么这个错误不应该发生。 @Abhineet 我完全按照我的预期检查了我的机器:/home/davidbo/workarea/workspace/test/Debug/../hellop.c:4: `HelloProc' 的多个定义跨度> 在哪里可以看到HelloProc的两个定义?正如您所说,#include 将像复制粘贴一样工作,因此整个“hellop.c”将在 hello.c 中替换并被编译。无论如何,我已经尝试过守卫(每当我被 LNK2005 击中时,他们是第一个尝试的),但似乎不起作用。 那么,守卫有帮助吗? :-) so include 是复制粘贴,这意味着在链接时你有两个HelloProc
的定义,一个在 hellop.obj 中它是第一次编译,在 hello.obj 中你得到另一个定义相同的功能。所以它编译了两次,现在它试图链接HelloProc
两次。以上是关于“已在目标文件中定义”和“找到一个或多个多重定义的符号”的主要内容,如果未能解决你的问题,请参考以下文章
全局变量重复定义,fatal error LNK1169: 找到一个或多个多重定义的符号
OpenGL 图像 (GLI):找到一个或多个多重定义的符号
error LNK1169: 找到一个或多个多重定义的符号”的解决方法(转载)