如何在 C 中使用外部联合数组?

How to use an extern union array in C?

我想使用一个类似于chux建议的联合数组

union {
  uint8_t u8[12];
  uint16_t u16[6];
} *array_u;

array_u = calloc(1, sizeof *array_u);
assert(array_u);

printf("array_u->u8[0] = %" PRIu8 "\n", array_u->u8[0]);

array_u->u16[0] = 1234;
printf("array_u->u16[0] = %" PRIu16 "\n", array_u->u16[0]);
...

来源:

我想将其用作不同文件需要访问它的全局数组。所以我尝试了 globals.h:

extern union {
    uint8_t u8[12];
    uint16_t u16[6];
} *array_u;

我想在这个文件中分配和释放它memory.c:

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdlib.h>
#include "globals.h"

void allocate_array_u(void){
    array_u = calloc(1, sizeof *array_u);
}

很遗憾我收到了 error LNK2001: unresolved external symbol array_u

我该如何解决?

解法: 我忘了在 main.cmemory.c:

中定义并集
array_u_t *array_u;

除了将 array_u 声明为 extern 之外,您还需要 定义 变量。 extern 只是说在其他地方找到定义。该定义需要存在于某处。

试试下面的方法。

更改globals.h如下:

typedef union {
    uint8_t u8[12];
    uint16_t u16[6];
} array_u_t;

extern array_u_t *array_u;

memory.c中定义array_u如下:

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdlib.h>
#include "globals.h"

array_u_t *array_u; // <---------------- definition

void allocate_array_u(void){
    array_u = calloc(1, sizeof *array_u);
}

您在每个包含 globals.h 的源文件中都将 array_u 声明为外部符号,但它位于何处?每个变量都必须在某处定义;即未声明为 external 并且可选,已初始化。

选择最合适的C文件并写入其中:

union {
    uint8_t u8[12];
    uint16_t u16[6];
} *array_u = NULL;

你最好使用 typedef 为变量的联合类型命名 array_u 以避免定义它两次。

写在globals.h:

typedef union {
    uint8_t u8[12];
    uint16_t u16[6];
} array_u_type;
extern array_u_type *array_u;

写入其中一个C文件(例如memory.c):

#include "globals.h"

array_u_type *array_u = NULL;

将上面示例中的 array_u_type 替换为您喜欢的新数据类型名称。

建议给工会起一个'tag'的名字。

union myunion 
{
    uint8_t u8[12];
    uint16_t u16[6];
};

然后在单独的语句中声明一个指向联合的指针的实例:

 union myunion *array_u = NULL;

然后将指向联合的指针设置为一个值:

array_u = calloc(1, sizeof union myunion);

注意:调用 assert() 不会告诉用户哪里出了问题,这在生产代码中是一个糟糕的选择。

相反,建议:

if( NULL == array_u )
{ // then calloc failed
    perror( "calloc for instance of union myunion failed: );
    exit( EXIT_FAILURE );
}

// implied else, calloc successful

注意:将文字 'NULL' 放在左侧,这样击键错误,例如键入 = 而不是 == 将被编译器捕获,而不是您花费数小时和小时寻找 'oops'.