-2

在 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. 获得编译成功的唯一方法是将 mTab​​ 声明和初始化放在 main.cpp 的主范围内......这不是我想要的!(在主范围内编译是可以的。在主范围外,即在包含级别,编译是KO)

感谢帮助,

跳频

~>more *

库文件

#include "lib.h"

void m1 ( unsigned int const iDataSize, int * const iopData ) { return; }
void m2 ( unsigned int const iDataSize, int * const iopData ) { return; }

库文件

#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

主文件

#include "lib.h"
#include <stddef.h> // NULL

int main ()
{
  (*mTab[0]) ( 0, NULL );
  (*mTab[1]) ( 0, NULL );

  return 0;
}

生成文件

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
4

3 回答 3

8

首先,只在共享头文件中放置声明,而不是对象或函数的定义。对于 mTab​​,在 lib.h 中使用它:

extern pF mTab[2];

其次,在一个且只有一个源文件中定义一个对象。把它放在 lib.cpp 中:

pf mTab[2] = { m1, m2 };

第三,mTab[0] = &m1;不是mTab的初始化。这将是一个赋值语句,但它在错误的位置,因为你不能在文件范围内有赋值语句。初始化 mTab​​ 的正确方法如上所示。(赋值不同于初始化。赋值是可执行语句,必须在函数体内。初始化是对象创建的一部分,可能发生在程序的主要执行之前。)

第四,static不使每个用户的对象都相同。它有两种效果,可能会因使用地点而异。在文件范围内使用时,表示标识符具有内部链接,即标识符引用当前编译中的对象;它没有在外部链接到其他编译中的相同标识符。所以它实际上与你写的相反;这意味着每个源文件都有自己的mTab,而不是它们共享一个mTab。(static的第二个作用static是给一个对象静态存储持续时间,所以它的生命周期是程序的整个执行过程。但是,这在文件范围内没有影响,因为在文件范围内声明的对象默认具有静态存储持续时间。)

于 2013-05-10T12:27:48.980 回答
1
mTab[0] = &m1;

你不能在全局命名空间中这样做。尝试在其中一个 cpps 中定义它并在标题中将其作为“extern”;

于 2013-05-10T12:26:25.280 回答
0

static在这种情况下意味着别的东西。static表示变量具有内部链接。这意味着每个编译单元将存在一个单独的变量。您想extern在标题中使用。

此外,请__lib__为您的包含防护选择不同的符号。包含双下划线的标识符保留给实现使用。

最后,正如 ahoka 所指出的,您不能将该代码放在命名空间范围内。这仅在函数中有效。所以这样做:

库文件

extern pF mTab[2];

库文件

pF mTab[2] = {&m1, &m2};
于 2013-05-10T12:26:36.067 回答