c++ - 在两个文件之间共享静态全局变量
问题描述
我有一个构建到静态库 libdefine.a 中的 def.cc 文件:
定义.h
#include<stdio.h>
#include <unistd.h>
void testFunction();
typedef struct _epoll_ctxt {
int epfd;
int last;
} epoll_ctxt;
默认文件
#include<stdio.h>
#include <unistd.h>
#include "def.h"
static int count = 0;
static epoll_ctxt g_epctxt;
void testFunction() {
g_epctxt.epfd = 5;
printf("The epfd value is %d and val from .h file", g_epctxt.epfd);
}
我已经使用 def.o 创建了库 libdefine.a 我想在 test.cc (驱动程序函数)中使用变量g_epctxt,所以我将代码编写为
测试.cc:
#include<stdio.h>
#include <unistd.h>
#include "def.h"
extern epoll_ctxt g_epctxt;
int main() {
testFunction();
g_epctxt.epfd = 8;
printf("The epfd value is %d", g_epctxt.epfd);
return 0;
}
使用命令编译:gcc test.cc -L。-ldefine 并得到以下错误:
/tmp/ccdr4Xi5.o:在函数“主”中: test.cc:(.text+0x10): 对“g_epctxt”的未定义引用 test.cc:(.text+0x19): 对“g_epctxt”的未定义引用 collect2: ld 返回 1 个退出状态
有人可以在这里帮助我我错过了什么。
解决方案
在def.cc
以下声明中表示具有内部链接的变量:
static epoll_ctxt g_epctxt;
C++ 标准第 6.6 节第 3.1 节:
具有命名空间范围的名称如果是
- 显式声明的变量、变量模板、函数或函数模板
static
此外,在第 6.6 节 §2.3 中:
当名称具有内部链接时,它所表示的实体可以由同一翻译单元中其他范围的名称引用。
static
因此,当您在翻译单元(在本例中为文件)中声明全局变量时def.cc
,您只能在同一翻译单元内引用它。具有内部链接的名称也被标准称为TU-locals(翻译单元本地人)。
根据第 6.6 节第 18 节,我们可以指出您的程序格式错误:
如果出现在一个翻译单元中的声明命名了在另一个不是标头单元的翻译单元中声明的 TU 本地实体,则该程序格式错误。
看起来您只想g_epctxt
在所有其他翻译单元中拥有该变量的单个实例。因此,您希望变量具有外部链接。为此,您只需在def.cc
没有说明符的情况下定义变量static
:
// def.cc
// Global variables have external linkage by default
epoll_ctxt g_epctxt;
extern
不过,在头文件 ( def.h
)中声明这种类型的变量也是一种很好的做法。这样您就不必每次使用它时都重新声明该变量,并且它还阐明了该变量旨在用于其他翻译单元:
// def.h
extern epoll_ctxt g_epctxt;
使用extern
上面的声明,您应该删除现在多余的g_epctxt
from声明test.cc
(和其他.cc文件):
// test.cc
// This is redundant and should be removed
extern epoll_ctxt g_epctxt;
您也可以这样想这个解决方案:如果您想更改变量的名称或类型g_epctxt
,您是否只想在def.cc
and中执行它def.h
,或者在它已声明的def.c
所有不同的.cc文件中执行。
推荐阅读
- reactjs - 调用 this.props.history.push 后如何进行组件更新?
- javascript - TypeError:使用 cloudinary 时无法读取未定义的属性“路径”
- javascript - IBM Watson WebSocket 连接失败。HTTP 认证失败;没有可用的有效凭证
- html - 无法减少图像和段落之间的额外空间
- dpdk - 在一个 VM 中运行 dpdk pktgen 和数据包捕获
- javascript - JS:如何隐藏引导模式以使输入数据不会持续存在?
- kubernetes - kubernetes helm:如何在父图表中设置子图表的环境变量
- r - 使用 atop() 时完全左对齐
- asp.net-mvc - auth0 回调 url 不存在
- python - 使用 Python 将 .dat 转换为 .mat