【发布时间】:2014-04-20 03:34:40
【问题描述】:
短版
我不明白如何可靠地初始化 python 扩展的静态成员。特别是,如何确保来自不同编译单元的代码具有特定的加载顺序,从而满足某些依赖关系?
加长版
我有一些代码可以多次计算各种组合函数,例如阶乘、二项式等。只需为这些东西构建一个表,然后对它们进行查找,效率会更高。而且我需要一个很好的接口来获取值,所以我只创建 c++ 类,将表作为静态成员。
作为最简单的示例,要计算阶乘,我有以下内容。在Combinatorics.hpp:
class FactorialFunctor {
private:
static const std::vector<double> FactorialTable;
public:
FactorialFunctor() { };
inline double operator()(const unsigned int i) const {
return FactorialTable[i];
}
};
在Combinatorics.cpp:
const std::vector<double> FactorialFunctor::FactorialTable = FactorialTableCalculator();
其中FactorialTableCalculator 是一个本地函数,它只返回适当的向量。 [那些operator()s 对于二项式等变得更加复杂,这就是我使用类来包装这些东西的原因。]
我使用 SWIG 将 c++ 代码包装起来,并在 python 中使用它。这一切都很顺利,直到我在我正在使用的新集群上编译了我的代码。现在我想我以前只是运气好。
只要我在新集群上导入我的 python 模块,python 就会出现段错误。 Python 甚至没有从导入步骤中恢复过来。使用gdb,我将其追踪到代码的另一部分,其初始化调用了Factorial 函子。但是FactorialTable 还没有被初始化,所以整个事情都呱呱叫了。
所以我需要确保在计算其他代码之前计算我的阶乘。我以所需的顺序告诉 distutils,但显然这不是他们在此集群上调用的顺序。链接过程中是否有某个阶段需要我小心处理?
【问题讨论】:
标签: python c++ swig python-extensions