来自C中单独文件的联合变量

时间:2015-11-11 16:30:52

标签: c embedded unions

是否可以将另一个文件中声明为extern的变量联合起来?这适用于需要保留内存的嵌入式应用程序,因此尽可能地共享。 即:

file1.h:

extern char Buffer1[ 10 ];

file2.h

extern char Buffer2[ 15 ];

···

typedef union
{
  Buffer1; 
  Buffer2;
} uBuffers;

我意识到这不是没有类型的正确语法,但如果使用了类型,则声明一个新变量。它们可以明确地放在RAM中,但这会消除灵活性。

编辑: 谢谢你的回答。 我应该弄清楚的是这种情况出现的原因。 我必须包含一些优化的汇编程序,它使用我希望结合在一起的变量。但是汇编语法不允许使用联合,即EXTERN uBuffers.Buffer1 - 生成语法错误。

4 个答案:

答案 0 :(得分:2)

extern声明只是告诉编译器这些变量存在于某个地方,以及它们的类型是什么。当您引用这些符号时,编译器将在代码中留下一个漏洞,链接器可以在知道后插入实际地址。您需要安排链接器为两个符号分配相同的地址。您可以声明一个名为Buffer1and2的联合类型的全局变量,然后使用一些内联asm来equBuffer1Buffer2Buffer1and2equ应在符号表中创建具有相同值(地址)的新符号。

请注意,这不适用于放置在.comm部分中的非静态或未初始化数据。这是一个非常丑陋的黑客,但它确实导致两个单独的全局变量出现在同一个地址,而它们看起来不是联盟成员......

dut.h

typedef char Buffer1[25];
typedef char Buffer2[30];

extern Buffer1 buffer1;
extern Buffer2 buffer2;

dut.c

#include "dut.h"

static union {
    Buffer1 buffer1;
    Buffer2 buffer2;
} bufferX;

__asm(".globl  buffer1\n"
      ".equ    buffer1, bufferX\n"
      ".globl  buffer2\n"
      ".equ    buffer2, bufferX\n");

的main.c

#include <stdio.h>
#include "dut.h"

int main(int argc, char **argv)
{
    buffer1[0] = 0xa5;
    printf("%02x\n", buffer2[0]);
    return 0;
}

请注意,如果您无法修改引用buffer1buffer2的代码,这应该是最后的选择。如果你可以修改代码,那么你应该只是一个联合,并让代码引用一个union的成员,如@Dmitri的回答中所述。

答案 1 :(得分:1)

组织这个的一个好方法是有一个定义结构的common_buffer.h并包含extern声明(不要忘记包含保护):

typedef union {
    uint16_t buf1[BUF1_SIZE];
    uint8_t  buf2[BUF2_SIZE];
} uBuffers_type;

extern uBuffers_type ubuffers_var;

您可以在现有编译单元(.c文件)中包含它的实际分配,也可以创建一个单独的common_buffer.c,其中包含

#include "common_buffer.h"
uBuffers_type ubuffers_var;

确保非外部变量声明在整个项目中只出现一次。从那以后,你

的任何文件
#include "common_buffer.h"

将能够使用类似

之类的缓冲区
ubuffers_var.buf1[index] = someUInt16;

someUInt8 = ubuffers_var.buf2[other_index];

答案 2 :(得分:0)

建议在一个文件中声明union,

一个常见的头文件需要一个&#39; extern&#39;为该联盟和工会定义。

使用该联合的每个文件都需要包含公共标题。

答案 3 :(得分:0)

我想你可能在这里误解了一些东西。

代码extern char Buffer1[ 10 ];表示在另一个文件中声明了一个对象。也就是说,已经分配了10个char s的空间,并且名称为Buffer1

代码typedef union { Buffer1; Buffer2; } uBuffers;仅定义名为uBuffers的数据类型。没有分配存储空间,在您声明存储空间之前不存在任何对象。

您不能使用union来获取两个已存在的对象,并告诉编译器它们应该共享相同的内存空间。您必须使用union 替换现有对象。例如,在两个源文件都可见的标题中使用类似的内容:

// create union data type
union my_union
{
    char Buffer1[10];
    char Buffer2[15];
};

// the real declaration needs to be added to a source file somewhere
extern union my_union buffers;

在您的特定情况下,两个对象都是char数组,因此更简单的解决方案是只有一个缓冲区,如char buffer[15];。当不同的成员具有截然不同的数据类型时,union方法通常更有用。