在标头中声明Struct并在多个源中使用

在标头中声明Struct并在多个源中使用,c,struct,C,Struct,我需要在源文件中定义一个结构,其他源也应该能够看到。 我在一个源文件中声明struct,然后在头文件中声明extern以包含在其他源文件中,但编译器存在以下错误: lcd.c(24): error: #147: declaration is incompatible with "struct graph_obj arrow_right" (declared at line 45 of "lcd.h") .C文件 struct graph_obj { const u16 *id;

我需要在源文件中定义一个结构,其他源也应该能够看到。 我在一个源文件中声明struct,然后在头文件中声明extern以包含在其他源文件中,但编译器存在以下错误:

lcd.c(24): error:  #147: declaration is incompatible with "struct graph_obj arrow_right" (declared at line 45 of "lcd.h")
.C文件

struct graph_obj
{
    const u16   *id;
    int x,y;
    u16 w, h;
};

u32 lcdid;

struct graph_obj btn0;
struct graph_obj btn1;
struct graph_obj btn2;
struct graph_obj btn3;
然后是.h文件

extern struct graph_obj
{
    const u16   *id;
    int x,y;
    u16 w, h;
};

extern u32 lcdid;

extern struct graph_obj btn0;
extern struct graph_obj btn1;
extern struct graph_obj btn2;
extern struct graph_obj btn3;

所以,我应该怎么做?

您需要在头文件中声明和定义结构,然后将此头文件包含到相应的源文件中。在源代码中包含所有原型和公共结构定义的标题是一个好主意,也是一种广泛应用的实践。正如在另一个答案中所建议的,“头部防护装置”是必须具备的

编辑:您定义了结构2次,这就是错误的来源。extern仅对变量有效,对原型无效

in header:  

typedef struct 
{
    const u16   *id;
    int x,y;
    u16 w, h;
}GRAPH_OBJ;


extern GRAPH_OBJ graph_obj, *pGraph_obj; 
在c模块中:

GRAPH_OBJ graph_obj, *pGraph_obj;  

与您的代码类似,只是在这里,您创建了一个新类型(GRAPH_OBJ),它的行为将与任何外部类型一样。而且,您不必完全重新创建结构定义,它都包含在GRAPH_OBJ中。顺便说一下,是一篇关于如何正确使用外部程序的好文章

你能帮我寄密码吗?从你写的东西看你在干什么,你应该做的是在头文件中显示出实际的代码/行,并在标题文件中显示相应的声明。只要添加了代码,tnxuse
typedef struct…
在h模块中,然后在相同的.h模块中显示typedef的d结构,然后,您可以使用该类型的结构在每个.c模块中需要的地方创建实例。请参阅下面的答案了解编码示例。我应该怎么做?@Beh,您应该在header(在您的示例中是lcd.h)中声明和定义所有原型(公共结构、前向声明、宏等)。别忘了在标题中加入卫兵,他们是你的朋友。然后将lcd.h包含到lcd.c。所有的公共内容都已经在lcd.h中了,您不应该在lcd.c中再次声明它们,因此,您只在lcd.c中添加了对lcd.c“私有”的内容(内部结构、函数定义、内部宏等)。欢迎使用。顺便说一句,我没有明确说明另一个好处(尽管在链接中有明确讨论),即由于以这种方式使用外部修饰符,因此以这种方式创建的结构具有项目可见性,即在一个.c模块中分配的成员值将与使用该结构的任何其他模块中的值相同。这可能很好,但如果不小心,这是一把双刃剑。所以让我问另一个问题。不使用extern声明会降低执行性能吗?我认为使用或不使用
extern
不会导致执行性能改变,但会导致程序的行为不同。i、 例如,通过以上面使用的方式使用extern,不仅可以使变量
GRAPH_OBJ
(您的结构)在每个.c模块中都可用,还可以使分配给其成员的值在使用该结构的每个.c模块中立即可见(如我前面所说)。但是,没有。我不认为使用
extern
会降低性能。