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

时间:2013-05-10 12:20:39

标签: c++

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

  1. 在lib.h中声明并初始化
  2. 在lib.cpp中实现
  3. 我无法做到这一点:出了什么问题?看来typedef被忽略了,我不明白为什么?

    注意:

    1. 由于每个lib.h用户的mTab必须相同,我添加了静态关键字
    2. 因为必须始终初始化静态变量(以避免意外行为),我在lib.h中初始化了mTab
    3. 当我在lib.cpp中移动mTab初始化时:编译是KO
    4. 当我在lib.cpp中移动mTab声明和初始化时,在main.cpp中使用“extern”:编译是KO
    5. 获得编译的唯一方法就是将mTab声明和初始化放在main.cpp的主要范围内......这不是我想要的! (主要范围内编译可以。外部主要范围,即包含级别,编译为KO)
    6. 感谢您的帮助,

      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;
      }
      

      生成文件

      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
      

3 个答案:

答案 0 :(得分:6)

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

extern pF mTab[2];

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

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

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

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

答案 1 :(得分:1)

mTab[0] = &m1;

您无法在全局命名空间中执行此操作。尝试在其中一个cpp中定义它,并在标题中将其作为“extern”;

答案 2 :(得分:0)

static在此上下文中表示其他内容。 static表示变量具有内部链接。这意味着每个编译单元都将存在一个单独的变量。您想在标题中使用extern

此外,请为{include}后卫选择__lib__以外的其他符号。包含双下划线的标识符保留供实现使用。

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

lib.h

extern pF mTab[2];

lib.cpp

pF mTab[2] = {&m1, &m2};