是否可以将另一个文件中声明为extern
的变量联合起来?这适用于需要保留内存的嵌入式应用程序,因此尽可能地共享。
即:
file1.h:
extern char Buffer1[ 10 ];
file2.h
extern char Buffer2[ 15 ];
···
typedef union
{
Buffer1;
Buffer2;
} uBuffers;
我意识到这不是没有类型的正确语法,但如果使用了类型,则声明一个新变量。它们可以明确地放在RAM中,但这会消除灵活性。
编辑: 谢谢你的回答。 我应该弄清楚的是这种情况出现的原因。 我必须包含一些优化的汇编程序,它使用我希望结合在一起的变量。但是汇编语法不允许使用联合,即EXTERN uBuffers.Buffer1 - 生成语法错误。
答案 0 :(得分:2)
extern
声明只是告诉编译器这些变量存在于某个地方,以及它们的类型是什么。当您引用这些符号时,编译器将在代码中留下一个漏洞,链接器可以在知道后插入实际地址。您需要安排链接器为两个符号分配相同的地址。您可以声明一个名为Buffer1and2
的联合类型的全局变量,然后使用一些内联asm来equ
吃Buffer1
和Buffer2
到Buffer1and2
。 equ
应在符号表中创建具有相同值(地址)的新符号。
请注意,这不适用于放置在.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;
}
请注意,如果您无法修改引用buffer1
和buffer2
的代码,这应该是最后的选择。如果你可以修改代码,那么你应该只是一个联合,并让代码引用一个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方法通常更有用。