从不同文件

时间:2015-06-26 05:16:47

标签: c extern

我声明了一个结构数组,并希望在一个文件中定义第一个数组组件,在另一个文件中定义第二个数组组件。以下是一个例子。

header.h

struct st1 {
  int a;
  int b;
}

file1.c中

struct st1 structure1[2];

我想使用不同文件中的初始化structure1组件,如下所示

file2.c中

extern struct st1 structure1[0] = { 10, 100 };

file3.c中

extern struct st1 structure1[1] = { 200, 500 };

另请注意,在file2.cfile3.c中,定义不在函数内部。

如果我尝试编译,链接器会抛出多个定义的错误。 在使用Google搜索后,我知道extern的定义只能发生一次。 我们可以在不同的源代码文件中完成extern数组的这种定义吗?

更多信息: file2.c和file3.c有常量,我将在file1.c中使用。我目前的实现是我在file2.c和file3.c中使用init()函数。 file1.c使用初始化值来决定执行过程。由于file2.c和file3.c是导出常量,我的目的是避免来自file1.c的另外两个init调用。

3 个答案:

答案 0 :(得分:3)

我试图尽可能地理解你想要的东西,我想你需要整理下面的文件。

头文件将包含整个项目中可用的共享符号引用以及一些函数:

////// header.h //////
struct st1 {
    int a;
    int b;
};

extern struct st1 structure1[2];

extern void init2();
extern void init3();

然后,包含符号的实现;你也可以在这里进行初始化:

////// file1.c //////
#include "header.h"

struct st1 structure1[2];

然后,您将在其中进行结构更改的代码文件;因为这不可能在编译时发生,你需要将它包装在你可以从其他地方调用的函数中。

////// file2.c //////
#include "header.h"

void init2()
{
    structure1[0] = (struct st1){10, 100};
}

////// file3.c //////    
#include "header.h"

void init3()
{
    structure1[1] = (struct st1){200, 500};
}

上面两个脚本都有一个初始化函数,可以调用它来写入结构。最后,一个演示行为的示例:

////// main.c //////
#include "header.h"
#include <stdio.h>

int main(void)
{
    init2();
    init3();

    printf("s[0].a = %d, s[1].a = %d\n", structure1[0].a, structure1[1].a);

    return 0;
}

像这样编译:

cc -o file file1.c file2.c file3.c main.c

答案 1 :(得分:2)

除非您的file2.cfile3.c被编译为不同的可执行文件,否则您的问题没有任何意义,因为某个给定的可执行文件不能具有某些相同变量的两个定义< /强>;您在大多数实施中都会收到linker错误。因此,我猜您有两个共享公共file1.cheader.h

的程序

因此,我们假设file2.cfile3.c被编译到不同的程序中。所以(在Linux上)你会编译并链接file1.c&amp; file2.c使用

进入proga计划
gcc -c -Wall -g file1.c
gcc -c -Wall -g file2.c
gcc file1.o file2.o -o proga

(或等同于Makefile规则),您可以编译并链接file1.c&amp; file3.c不同的 progb计划

gcc -c -Wall -g file1.c
gcc -c -Wall -g file3.c
gcc file1.o file3.o -o progb

当然,所有file1.cfile2.cfile3.c都有#include "header.h"指令。显然,file1.c的编译可以完成一次(并且make会处理这个问题),重复使用file1.oproga的对象文件progbheader.h

然后你可能应该在// in header.h extern struct st1 structure1[];

中声明
structure1

并且您无法在另一个文件(实际翻译单元)中定义structure1[0]的每个组件。因此,您无法填写file2.c中的structure1[1]&amp; file3.c中的fill_first(除非您在运行时填写一些明确的例程,例如fill_second&amp; main,您可以明确地调用它们,例如在{{1}的开头}})

您可以做的是(因为file2.o仅在proga中链接,而file3.o仅在progb中与file2.c中的file3.c具有不同的定义)在structure1中(但定义是定义整个 // in file2.c struct st1 structure1[2] = { {1,2}, {3,4} }; ,而不是它的某些部分!)所以你可能有

 // in file3.c
 struct st1 structure1[3] = { {0,1}, {2,3}, {3,4} };

init.c

实际上,您可能有一个structure1文件(仅包含数据的定义(如#if),它可能会使用预处理器技巧(例如#ifdefproga指令)对progb&amp; init-proga.o进行不同的初始化;您可能需要以不同的方式将其编译为两个不同的目标文件,例如init-progb.o&amp; http://developer.android.com/guide/topics/media/mediaplayer.html http://code.tutsplus.com/tutorials/create-a-music-player-on-android-song-playback--mobile-22778 ,...

答案 2 :(得分:1)

header.h文件中

struct st1 {
    int a;
    int b;
};

extern struct st1 structure1[2];  /* Have your declaration here */

在您的.c个文件中,例如file1.c,您可以定义您的结构:

struct st1 structure1[2];  /* Define your structure here */

void func1()
{
  structure[0].a = 10;
  structure[0].b = 100;
}

file2.c

#include "header.h"  /* Make the declaration of your structure visible here */

void func2()
{
  structure[1].a = 200;
  structure[1].b = 500;
}

当然,在两个函数都被调用之前,结构不会被完全初始化。