全部博文(290)
分类: WINDOWS
2011-02-24 00:20:19
正写个罗云斌所著
先是源文件代码(为方便实验找出问题而简化的相关代码):main.c
01 #include
02 #include "msgqueue.h"
03 #pragma comment(linker, "/subsystem:windows /RELEASE ")
04
05 extern QUEUE_INSTANCE Queue_Instance; //关键语句A
06
07 int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
08 {
09 Queue_Instance.iMsgCount=0;
10 Queue_Instance.iMsgSequence=0;
11 return 0;
12 }
下面第二个源文件:MsgQueue.h
01 #define MAX_CHAR 256
02 #define QUEUE_SIZE 500
03 typedef struct {
04 int iMsgId;
05 char szSender[12];
06 char szContent[MAX_CHAR];
07 } MSG_QUEUE_ITEM;
08
09 typedef struct {
10 int iMsgCount;
11 int iMsgSequence;
12 MSG_QUEUE_ITEM MsgQueue[QUEUE_SIZE];
13 }QUEUE_INSTANCE;
14
15 QUEUE_INSTANCE Queue_Instance={0}; //关键语句B
下面第三个源文件:MsgQueue..c
01 #include
02 #include "msgqueue.h"
03
04 //Queue_Instance={0};
05 void InsertMsgQueue(char *lpszSender,char *lpszContent)
06 {
07 int i;
08
09
10 if (Queue_Instance.iMsgCount>=QUEUE_SIZE)//里面要用Queue_Instance实例
11 {
12 for (i=0;i
13 {
14 Queue_Instance.MsgQueue[i]=Queue_Instance.MsgQueue[i+1];
15 }
16 Queue_Instance.iMsgCount=i;
17 }
18 }
先发布官方解释及处理方案:
1.Linker Tools Error LNK1169
one or more multiply defined symbols found
The build failed due to multiple definitions of one or more symbols. This error is preceded by error LNK2005.
The /FORCE or /FORCE:MULTIPLE option overrides this error.
也就是"在 Project/Setting/Link/General中的 Project Options: 加入 /FORCE:MULTIPLE即可"
2.Linker Tools Error LNK2005
symbol already defined in object
The given symbol, displayed in its decorated form, was multiply defined.
Tips
One of the following may be a cause:
This error is followed by fatal error LNK1169.
< src="MS-ITS://dsmsdn.chm">
< src="MS-ITS://dsmsdn.chm">
看玩MSDN的箴言,抄家伙,改为多线程运行时进行编译,得到结果:失败
强制输出文件,得到结果:不算失败,但没解决多实例问题:warning LNK4088: image being generated due to /FORCE option; image may not run,不保险啊.
看了N篇文章,没有对策.代码少,无意间把QUEUE_INSTANCE Queue_Instance={0}; //关键语句B
中的初始化部分={0}; 移到另一个文件MsgQueue.c,进行编译,得到结果:OK
实验收获:对全局数据的初始化要放在源文件中,不能放在头文件中
以下为转载网上的经典分析文章,借鉴下:
fatal error LNK1169: one or more multiply defined symbols found
属于编译联接的常见问题之一,原因是在不同的源文件重复定义变量。比如project1有2个.c或.cpp文件,假设为a.c,b.c,如果
1:定义了相同名字的变量;
2:包含了同样的头文件(其中定义了非局部变量);
这样在编译生成的a.obj,b.obj文件中都会为为这个同一变量 分配空间,linker会作名称检查,如果出现相同名字就会出现:
fatal error LNK1169: one or more multiply defined symbols found
解决方法:对于第一种情况,用external关键字屏蔽其它重复定义即可; 实际上情况2更隐蔽常见,只能避免定义非局部变量。
//////////////////////////////////////////////////////////////
大家都知道,从C/C++源程序到可执行文件要经历两个阶段:(1)编译器将源文件编译成汇编代码,然后由汇编器
(assembler)翻译成机器指令(再加上其它相关信息)后输出到一个个目标文件(object
file,VC的编译器编译出的目标文件默认的后缀名是.obj)中;(2)链接器(linker)将一个个的目标文件(或许还会有若干程序库)链接在一
起生成一个完整的可执行文件。
编译器编译源文件时会把源文件的全局符号(global
symbol)分成强(strong)和弱(weak)两类传给汇编器,而随后汇编器则将强弱信息编码并保存在目标文件的符号表中。那么何谓强弱呢?编译
器认为函数与初始化了的全局变量都是强符号,而未初始化的全局变量则成了弱符号。比如有这么个源文件:
extern int errorno;
int buf[2] = {1,2};
int *p;
int main()
{
return 0;
}
其中main、buf是强符号,p是弱符号,而errorno则非强非弱,因为它只是个外部变量的使用声明。
有了强弱符号的概念,我们就可以看看链接器是如何处理与选择被多次定义过的全局符号:
规则1: 不允许强符号被多次定义(即不同的目标文件中不能有同名的强符号);
规则2: 如果一个符号在某个目标文件中是强符号,在其它文件中都是弱符号,那么选择强符号;
规则3: 如果一个符号在所有目标文件中都是弱符号,那么选择其中任意一个;
由上可知多个目标文件不能重复定义同名的函数与初始化了的全局变量,否则必然导致LNK2005和LNK1169两种链接错误。可是,有的时候我们并没有在自己的程序中发现这样的重定义现象,却也遇到了此种链接错误,这又是何解?嗯,问题稍微有点儿复杂,容我慢慢道来。
众
所周知,ANSI C/C++
定义了相当多的标准函数,而它们又分布在许多不同的目标文件中,如果直接以目标文件的形式提供给程序员使用的话,就需要他们确切地知道哪个函数存在于哪个
目标文件中,并且在链接时显式地指定目标文件名才能成功地生成可执行文件,显然这是一个巨大的负担。所以C语言提供了一种将多个目标文件打包成一个文件的
机制,这就是静态程序库(static
library)。开发者在链接时只需指定程序库的文件名,链接器就会自动到程序库中寻找那些应用程序确实用到的目标模块,并把(且只把)它们从库中拷贝
出来参与构建可执行文件。几�