C/C++:从.h导出变量

C/C++ : exporting variable from a .h

本文关键字:变量 C++      更新时间:2023-10-16

在C/C++中,我想从main.cpp使用一个现成的变量(mTab(,即:

  1. 在lib.h中声明并初始化
  2. 在lib.cpp中实现

我做不到:怎么了?似乎typedef被忽略了,我不明白为什么?

注:

  1. 由于每个lib.h用户的mTab都必须相同,所以我添加了static关键字
  2. 由于静态变量必须始终初始化(以避免意外行为(,我在lib.h中初始化了mTab
  3. 当我在lib.cpp中移动mTab初始化时:编译被KO
  4. 当我在lib.cpp中移动mTab声明和初始化,并在main.cpp中使用"extern"时:编译是KO
  5. 获得编译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};