使用 Boost 暴露静态常量

Posted

技术标签:

【中文标题】使用 Boost 暴露静态常量【英文标题】:Exposing Static Constant with Boost 【发布时间】:2011-07-29 18:44:25 【问题描述】:

我正在使用 Boost 1.44.0 为 Python 交叉编译 C++ 代码。我正在尝试公开 ExposureSinusoid.h 中定义的静态常量,如下所示:

static const UINT _min_exp = 20;

根据 Boost 团队的文档,在文件扩展.cpp 中,我试图像这样公开它们:

.def_readonly("_min_exp", &ExposureSinusoid::_min_exp)

该库编译正常,但程序运行时出现以下错误:

ImportError: ../linux/appfs/master/usr/lib/python2.6/pa/vision/_vision.so: undefined symbol: _ZN16ExposureSinusoid8_min_expE

为了排除 Boost 没有找到常量的可能性,我尝试在 extension.cpp 中更改其名称,但库无法编译。因此,似乎在编译期间发现了该常量,但没有正确公开。

【问题讨论】:

【参考方案1】:

除了被声明static 数据成员也必须被定义

// ExposureSinusoid.h
class ExposureSinusoid

    // ...
public:
    static const UINT _min_exp = 20;   // declaration
    // ...
;

// ExposureSinusoid.cpp
const UINT ExposureSinusoid::_min_exp; // definition

static 数据成员的定义可以省略的唯一情况是当相关数据成员是 const 基本整数类型时,并且它使用常量表达式初始化, and 它从不使用 ODR(参见 C++03 标准,§9.4.2/4);但是,获取变量的地址符合 ODR 使用的条件,因此在您的情况下,必须提供定义。

【讨论】:

不能在课堂上做这样的作业。分配需要与定义。 @crashmstr : 对static 数据成员允许内联初始化,这些数据成员是使用常量表达式初始化的const 基本整数类型。 这是来自较新的 c++ 规范之一吗? @crashmstr :不,它在 C++03 标准中,第 9.4.2/4 节。 那我有点过时了,因为我的书(第 3 版)中没有 9.4。【参考方案2】:

静态链接意味着符号在 TU 之外可见!将static 更改为extern(因为全局常量是隐式静态的):

extern const UINT _min_exp = 20;

更正:我没有看到 _min_exp 是一个成员变量,抱歉。在这种情况下,正如 ildjarn 已经说过的那样,答案是在类定义之外添加变量的定义。可以肯定的是,声明和初始化都在内部,但定义在外部:

struct Foo 
  static const int a = 1; // initialization can go inside the class definition
;
const int Foo::a;         // definition (this is what the linker sees)

【讨论】:

_min_exp 不是全局变量,它是class ExposureSinusoid 的数据成员。 哦,对不起,我的错误。是的,在这种情况下,您必须在类之外实际定义变量。

以上是关于使用 Boost 暴露静态常量的主要内容,如果未能解决你的问题,请参考以下文章

单例模式

如何使用boost.python中的-fPIC编译静态库

boost库,使用动态库(dll)好呢,还是静态库(lib)好呢?

每天一个设计模式之单例模式

boost::mpi 作为模板类的静态成员

代码块、MinGW、Boost 和静态链接问题