C/C++:从.h导出变量
C/C++ : exporting variable from a .h
在C/C++中,我想从main.cpp使用一个现成的变量(mTab(,即:
- 在lib.h中声明并初始化
- 在lib.cpp中实现
我做不到:怎么了?似乎typedef被忽略了,我不明白为什么?
注:
- 由于每个lib.h用户的mTab都必须相同,所以我添加了static关键字
- 由于静态变量必须始终初始化(以避免意外行为(,我在lib.h中初始化了mTab
- 当我在lib.cpp中移动mTab初始化时:编译被KO
- 当我在lib.cpp中移动mTab声明和初始化,并在main.cpp中使用"extern"时:编译是KO
- 获得编译OK的唯一方法是将mTab声明和初始化放在main.cpp的主作用域内…这不是我想要的!(主范围内编译可以。主范围外,即包含级别,编译被KO(
感谢您的帮助,
FH-
~>more *
lib.cpp
#include "lib.h"
void m1 ( unsigned int const iDataSize, int * const iopData ) { return; }
void m2 ( unsigned int const iDataSize, int * const iopData ) { return; }
lib.h
#ifndef __lib__
#define __lib__
void m1 ( unsigned int const iDataSize, int * const iopData );
void m2 ( unsigned int const iDataSize, int * const iopData );
typedef void ( *pF ) ( unsigned int const iDataSize, int * const iopData );
static pF mTab[2]; // Ready-to-use variable to be exported
mTab[0] = &m1;
mTab[1] = &m2;
#endif
main.cpp
#include "lib.h"
#include <stddef.h> // NULL
int main ()
{
(*mTab[0]) ( 0, NULL );
(*mTab[1]) ( 0, NULL );
return 0;
}
Makefile
all:
gcc -I. -c lib.cpp -o lib.o
gcc -I. -c main.cpp -o main.o
gcc -I. lib.o main.o -o main.exe
控制台:
~>make
gcc -I. -c lib.cpp -o lib.o
In file included from lib.cpp:1:0:
lib.h:7:1: error: ‘mTab’ does not name a type
lib.h:8:1: error: ‘mTab’ does not name a type
make: *** [all] Error 1
首先,只在共享头文件中放入声明,而不是对象或函数的定义。对于mTab,在lib.h:中使用它
extern pF mTab[2];
其次,在一个且只有一个源文件中定义一个对象。把这个放在lib.cpp:中
pf mTab[2] = { m1, m2 };
第三,mTab[0] = &m1;
不是mTab的初始化。这将是一个赋值语句,但它位于错误的位置,因为在文件范围内不能有赋值语句。初始化mTab的正确方法如上所示。(赋值不同于初始化。赋值是可执行的语句,必须在函数体内部。初始化是创建对象的一部分,可能发生在程序的主要执行之前。(
第四,static
不会使对象对于每个用户都是相同的。它有两种效果,可能因使用地点而异。当在文件范围内使用时,它表示标识符具有内部链接,这意味着标识符仅引用当前编译中的对象;它不是外部链接到其他汇编中的同一标识符。所以它实际上意味着与你所写的相反;这意味着每个源文件都有自己的mTab
,而不是说它们共享一个mTab
。(静态static
的第二个作用是为对象提供静态存储持续时间,因此它的生存期是程序的整个执行。但是,这在文件范围内没有影响,因为在文件范围声明的对象默认情况下具有静态存储持续期。(
mTab[0] = &m1;
在全局命名空间中不能这样做。尝试在其中一个cpp中定义它,并在标头中将其作为"extern";
static
在此上下文中表示其他含义。static
表示变量具有内部链接。这意味着每个编译单元将存在一个单独的变量。您希望在页眉中使用extern
。
此外,请选择除__lib__
之外的其他符号作为包含防护。包含双下划线的标识符保留给实现使用。
最后,正如ahoka所指出的,您不能将该代码放在名称空间范围内。这只在函数中有效。这样做吧:
lib.h
extern pF mTab[2];
lib.cpp
pF mTab[2] = {&m1, &m2};
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 将数组的地址分配给变量并删除
- 为"adjacent"变量赋值时出现问题
- enum是C++中的宏变量还是整数变量
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 用C++中的一个变量定义一个常量
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 你能重载对象变量名本身返回的内容吗
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 尝试通过多个向量访问变量时,向量下标超出范围
- 试图让变量检查数组中的某些内容
- Cpp-Tuple使用带有变量的get
- 将包含C样式数组的对象初始化为成员变量(C++)
- 当vector是tje全局变量时,c++中vector的内存管理
- 通过多个头文件使用常量变量
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 执行函数时导致崩溃的变量
- 变量没有改变?通过向量的函数调用