C 中的共享全局变量

问题描述 投票:0回答:7

如何创建在 C 中共享的全局变量?如果我将其放入头文件中,则链接器会抱怨变量已定义。这是在我的一个 C 文件中声明变量并手动将

extern
放在所有其他想要使用它的 C 文件顶部的唯一方法吗?听起来不太理想。

c variables linker global-variables scope
7个回答
99
投票

在一个头文件(shared.h)中:

extern int this_is_global;

在要使用此全局符号的每个文件中,包含包含 extern 声明的标头:

#include "shared.h"

为了避免多个链接器定义,您的编译单元中必须只存在一个全局符号声明(例如:shared.cpp):

/* shared.cpp */
#include "shared.h"
int this_is_global;

71
投票

在头文件中用

extern
写入。 并且在其中一个 c 文件的全局范围内声明它而不使用
extern


22
投票

头文件share.h中:

#ifndef SHAREFILE_INCLUDED
#define SHAREFILE_INCLUDED

#ifdef  MAIN_FILE
int global;
#else
extern int global;
#endif

#endif

在您希望全局变量所在的源文件中使用以下内容:

#define MAIN_FILE
#include "share.h"

在需要

extern
版本的其他文件中,使用:

#include "share.h"

16
投票

您将声明放入头文件中,例如

 extern int my_global;

在您的 .c 文件之一中,您在全局范围内定义它。

int my_global;

每个想要访问

my_global
的 .c 文件都包含带有
extern
的头文件。


6
投票

如果您在 C 和 C++ 之间共享代码,请记住将以下内容添加到

shared.h
文件中:

#ifdef __cplusplus
extern "C" {
#endif

extern int my_global;
/* other extern declarations ... */

#ifdef __cplusplus
}
#endif

2
投票

有一种更简洁的方法,只需一个头文件,因此更易于维护。 在带有全局变量的标头中,每个声明都带有关键字(我使用 common),然后在一个源文件中像这样包含它

#define common
#include "globals.h"
#undef common

以及任何其他类似的源文件

#define common extern
#include "globals.h"
#undef common

只需确保您没有初始化 globals.h 文件中的任何变量,否则链接器仍然会抱怨,因为即使使用 extern 关键字,初始化的变量也不会被视为外部变量。 global.h 文件看起来与此类似

#pragma once
common int globala;
common int globalb;
etc.

似乎适用于任何类型的声明。当然不要在 #define 上使用 common 关键字。


0
投票

有一种更优雅的方式来创建全局变量。

只需在“.c”源文件中将变量声明为静态并创建 set/get 函数。

下面的示例是我在内存分配测试期间用来覆盖 malloc、realloc 和 free 函数的。

示例:

内存分配器.h

#ifndef MEMORY_ALLOCATOR_H_
#define MEMORY_ALLOCATOR_H_

#include <stddef.h>

void std_set_memory_allocators(void *(*malloc)(size_t size),
                               void *(realloc)(void *ptr, size_t size),
                               void (*free)(void *ptr));

void std_set_reset_allocators();

void *std_malloc(size_t size);

void *std_realloc(void *ptr, size_t size);

void std_free(void *ptr);

#endif  // MEMORY_ALLOCATOR_H_

内存分配器.c

#include "memory-allocator.h"

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct {
    void *(*malloc)(size_t size);
    void *(*realloc)(void *ptr, size_t size);
    void (*free)(void *ptr);
} StdMemoryAllocator;

StdMemoryAllocator memory_allocators = {&malloc, &realloc, &free};

void std_set_memory_allocators(void *(*malloc)(size_t size),
                               void *(realloc)(void *ptr, size_t size),
                               void (*free)(void *ptr)) {
    memory_allocators.malloc = malloc;
    memory_allocators.realloc = realloc;
    memory_allocators.free = free;
}

void std_set_reset_allocators() {
    memory_allocators.malloc = malloc;
    memory_allocators.realloc = realloc;
    memory_allocators.free = free;
}

void *std_malloc(size_t size) {
    return memory_allocators.malloc(size);
}

void *std_realloc(void *ptr, size_t size) {
    return memory_allocators.realloc(ptr, size);
}

void std_free(void *ptr) {
    memory_allocators.free(ptr);
}

结构体

static struct StdMemoryAllocator_s memory_allocators
在应用程序启动时自动启动,它指向默认的C内存分配器。

© www.soinside.com 2019 - 2024. All rights reserved.