如何在C中使用extern union数组?

时间:2016-01-01 23:39:18

标签: c arrays extern unions

我想使用类似于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]);
...

来源:Is it okay to store different datatypes in same allocated memory in C?

我想将它用作不同文件需要访问它的全局数组。所以我尝试了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;

3 个答案:

答案 0 :(得分:6)

除了将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;

array_u中定义memory.c,如下所示:

#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);
}

答案 1 :(得分:1)

您在包含array_u但位于其中的每个源文件中将globals.h声明为外部符号?每个变量都必须在某处定义;即未声明为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中替换为您喜欢的新数据类型的任何名称。

答案 2 :(得分:1)

建议给联盟一个“标签”名称。

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

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

 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”,因此键入错误(如键入=而不是==)将被编译器捕获,而不是花费数小时和数小时来查找'糟糕'。