2017-08-01 89 views
0

我在dbinfo.h中有一个简单的结构,在C中的函数之间共享数据值

typedef struct { 
    int fields; 
} dbinfo; 

在主程序中我有:

#include <string.h> 
... 
#include "dbinfo.h" 
extern dbinfo *tst_info; 

void main() { 

tst_info = (dbinfo *) calloc(1, sizeof(dbinfo)); 

dbinfo.fields = 3; 

printf("\n number of fields = %d"), getnumflds()); 
... 
} 

在另一个文件utilities.c我

#include "dbinfo.h" 
extern dbinfo *tst_info; 

int getnumflds() { 

    return tst_info.fields; 
} 

当我试图链接我得到了一个未定义符号的utilities.c tst_info。 如果我删除extern,那么我得到没有未解决的符号,但字段的值是0.

我在这里做错了什么?

我只是希望能够使用和更改在其他函数分别编译的main中设置的'fields'的值。

因为我使用C并且无法访问这些神经元,所以一直很长时间!

+2

没错,说多一点。 Extern只是告诉“变量是其他编译器,相信我”。但是你从来没有真正做到过,所以链接器没有找到它。 只需从其中一个文件中移除extern。 –

+0

不明白。在主程序中,我指定它是extern并分配它。 –

+0

当我从主程序中删除外部函数,并且在子程序中引用“字段”时,即使我在主程序中将其设置为3,它也为零。 –

回答

2

tst_info的所有定义必须是extern,除了一个。某个对象文件中某个变量的extern关键字告诉链接程序不要在数据段中为它分配空间,因为该变量的存储将在某个其他目标文件中提供。如果所有目标文件都将变量定义为extern,则不存在为其提供存储的目标文件。

你可以阅读更多关于这方面比你能在这个岗位处理: https://stackoverflow.com/a/1433387/773113

+0

细节:“必须extern除了一个”稍微超过状态。 'extern int foo; int foo; int foo = 5;'作为int foo有效;'是暂定义。 – chux

+0

@chux是真实的,但我不确定我怎样才能避免过度陈述,同时避免提出一种不可移植的做法,因此是不可取的。 –

1

您在两个翻译单元中声明tst_infoexternextern关键字表示它在其他地方可用,在某些extern al翻译团结。在某处,您需要实际上通过而不是来定义extern关键字,而是设置一个初始值(可以是callocNULL或其他内容的结果)。

根据程序的用途,您可能会发现声明全局dbinfo而不是dbinfo *更容易。您可以移出动态运行时分配的数据越多越好。