使用多个文件在{C}应用程序中定义外部变量

时间:2016-04-07 19:13:19

标签: c extern

这是我面临的具体问题。

我有一个带有文件的应用程序 Names.c Names.h Names_e.c Names_e.h Names_f.c Names_f.h,以及其他文件。 Names.c使用在Names_e(.h和.c)中声明和定义的字符串来定义自己的数组变量。类似地,这些数组的第二个元素来自Names_f(.h和.c)中定义的字符串。

现在我将Names_e.h和Names_f.h中的所有元素定义为'extern'变量。当我只在Names.c中包含头文件Names_e.h和Names_f.h时,为什么我的应用程序会抛出“未解析的符号”错误?我必须包括各自的.c文件,即Names_e.c和Names_f.c,以消除错误。

我认为'extern'关键字告诉编译器该定义在代码中的其他位置。那么包括头文件在内是否足够?

将欣赏任何输入。提前致谢。

Names.c

#include Names_e.h
#include Names_f.h
const DISPSTRING * const * s_MenuName[2] =            {s_MenuName_e,
                                                      s_MenuName_f};

Names_e.c

const DISPSTRING M1                 = {0,"1."};
const DISPSTRING M2                 = {0,"2."};
const DISPSTRING M3                 = {0,"3."};
const DISPSTRING * const s_MenuName_e[3]    =  {&M1,&M2,&M3}; 

Names_f.c

const DISPSTRING M1_f                   = {0,"1."};
const DISPSTRING M2_f                   = {0,"2."};
const DISPSTRING M3_f                   = {0,"3."};
const DISPSTRING * const s_MenuName_e[3]    =  {&M1_f,&M2_f,&M3_f};

在Names.h

#include Names_e.h
#include Names_f.h

extern const DISPSTRING * const * s_MenuName[2];

Names_e.h

extern const DISPSTRING * const s_MenuName_e[3];

Names_f.h

extern const DISPSTRING * const s_MenuName_f[3];

答案 - >它不是代码,而是需要更改的makefile(将新文件添加到源文件和头文件列表以及添加相应的目标文件位置)。 我错误地认为IDE会自动执行此操作!谢谢大家发布的解决方案。

2 个答案:

答案 0 :(得分:0)

  

现在我将Names_e.h和Names_f.h中的所有元素定义为'extern'变量。当我只在Names.c中包含头文件Names_e.h和Names_f.h时,为什么我的应用程序会抛出“未解析的符号”错误?

[...]

  

我认为'extern'关键字告诉编译器该定义在代码中的其他位置。那么包括头文件在内是否足够?

extern关键字 表示所声明的对象或函数是在别处定义的。因此,如果在代码中引用该对象,则“其他地方”也需要链接到(或编译到)代码中。

  

我必须包含各自的.c文件,即Names_e.c和Names_f.c以删除错误。

你不应该这样做,也不应该这样做。但是如果有问题的应用程序由所有这些文件组成,那么要构建可执行文件,您需要编译所有这些文件并将它们链接在一起。你究竟如何做到这一点在某种程度上取决于你的工具链,但传统上,有两种通用方法:

  1. 通过在编译命令中指定所有.c文件的名称,一次编译所有源。 (这与#include另一个.c文件非常不同。)

  2. 将每个来源单独编译为中间“对象文件”表单,然后将它们全部链接在一起。

  3. 你不能混搭。也就是说,如果您打算使用第二种替代方法,那么您必须确保编译为目标文件格式。这通常需要额外的编译器标志,您不会将其用于选项(1)。

    gcc为例,选项(1)可能如下所示:

    gcc -o myprog Names.c Names_e.c Names_f.c other.c
    

    而选项(2)可能如下所示:

    gcc -c Names.c
    gcc -c Names_e.c
    gcc -c Names_f.c
    gcc -c other.c
    gcc -o myprog Names.o Names_e.o Names_f.o other.o
    

    但是如果你尝试gcc Names.c那么它会尝试单独从Names.c构建可执行程序,并且由于(至少)你描述的未实现的外部定义而失败。

答案 1 :(得分:0)

C关键字extern为其应用的对象提供了所谓的外部范围。典型的应用是 delare 变量 extern 在头文件 一次 中的 extern ,然后在a中初始化它。 c文件#include'头文件 一次 ,然后在#include s的任何其他.c中使用该变量标题。包含创建extern变量的标头(即在其他.c文件中)的位置,该变量的值是可见且可用的。

示例:

  

some.h:

extern int gVariable;
void func1(void);
  

some.c:

#include "some.h"

int gVariable = 0;

    int main(void)
    {
        gVariable = 10:
        func1();
        ...

        return 0;
    }
  

someOther.c:

#include "some.h"

void func1(void)
{
    printf("%d", gVariable);
}