我收到链接器的错误,例如:
osd.o(.ndata+0x514):C:\Documents and Settings\Thomas\My Documents\PIC\dsPIC33FJ128GP802\On Screen Display\osd.c: multiple definition of `video_buff_vis_num'
main.o(.ndata+0x0):C:\Documents and Settings\Thomas\My Documents\PIC\dsPIC33FJ128GP802\On Screen Display\main.c: first defined here
osd.o(.ndata+0x515):C:\Documents and Settings\Thomas\My Documents\PIC\dsPIC33FJ128GP802\On Screen Display\osd.c: multiple definition of `video_buff_draw_num'
main.o(.ndata+0x1):C:\Documents and Settings\Thomas\My Documents\PIC\dsPIC33FJ128GP802\On Screen Display\main.c: first defined here
osd.o(.ndata+0x516):C:\Documents and Settings\Thomas\My Documents\PIC\dsPIC33FJ128GP802\On Screen Display\osd.c: multiple definition of `vid_format'
main.o(.ndata+0x2):C:\Documents and Settings\Thomas\My Documents\PIC\dsPIC33FJ128GP802\On Screen Display\main.c: first defined here
osd.o(.ndata+0x518):C:\Documents and Settings\Thomas\My Documents\PIC\dsPIC33FJ128GP802\On Screen Display\osd.c: multiple definition of `vid_line'
main.o(.ndata+0x4):C:\Documents and Settings\Thomas\My Documents\PIC\dsPIC33FJ128GP802\On Screen Display\main.c: first defined here
这让我感到烦恼,因为在源代码中,我已经在这些定义可能来自的唯一地方加入了警卫。
#ifndef OSD_H
#define OSD_H
// code here, including definitions for the above
#endif // OSD_H
这让我很紧张。我已经清理,重建,并再次尝试。我甚至从头开始使用相同的文件创建一个新项目,我遇到了完全相同的问题!有人请赐教我为什么这不起作用! :)
使用PIC-GCC v3.23(PIC24F / H和dsPIC30F / 33F微控制器的GCC版本)进行编译。
如果有人想查看更多文件的来源,请告诉我。我不想过度拥挤这个页面。
答案 0 :(得分:6)
如果您在多个.c
文件中包含此标头,则您将拥有多个定义。你有main.c
和osd.c
。
.h
是函数和 extern
数据声明的正确位置。但是对于变量,您必须选择一个源文件。 #defined
警卫不会改变这一点。
另见this question。 this answer描述了标准模式。
还有一点解释/分析:
1)每个.c
源文件都是独立编译。警卫只能防止在1次编译期间两次读取头文件。
2)您获得的错误是链接器(而不是编译器)错误。
当标头定义变量时,编译器会将其视为每个单独运行中的定义。链接器将检测多个实例。
答案 1 :(得分:0)
您的包含文件包含哪些内容?
int video_buff_vis_num;
extern int video_buff_vis_num;
前者还是后者?前者没有定义变量但是为它分配内存,而后者只是说“某处是具有该名称的变量”。
您必须只有一个地方可以分配它,但您可以有很多定义。