使用Boost暴露静态常量

0 投票
2 回答
2676 浏览
提问于 2025-04-16 22:32

我正在使用Boost 1.44.0来为Python交叉编译C++代码。我想要暴露一个在ExposureSinusoid.h中定义的静态常量,像这样:

static const UINT _min_exp = 20;

然后在文件extending.cpp中,我想按照Boost团队的文档来暴露这些常量,像这样:

.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没有找到这个常量的可能性,我尝试在extending.cpp中更改它的名字,结果库编译失败。所以看起来这个常量在编译时是被找到的,但没有被正确暴露出来。

2 个回答

3

静态链接意味着这个符号在当前的翻译单元(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)
4

除了需要声明static数据成员还必须定义

// ExposureSinusoid.h
class ExposureSinusoid
{
    // ...
public:
    static const UINT _min_exp = 20;   // declaration
    // ...
};

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

唯一可以省略static数据成员定义的情况是,当这个数据成员是一个const类型的基本整型,并且它是用一个常量表达式初始化的,同时它在程序中从未被使用(参考C++03标准,§9.4.2/4);不过,获取一个变量的地址就算是使用了它,所以在你的情况下,必须提供一个定义。

撰写回答