简洁版本
我不明白如何可靠地初始化 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();
whereFactorialTableCalculator
是一个本地函数,它只返回适当的向量。[operator()
对于二项式等,这些变得更加复杂,这就是我使用类来包装这些东西的原因。]
我使用 SWIG 来包装c++
代码,并从 python 中使用它。这一切都很顺利,直到我在我正在使用的新集群上编译了我的代码。现在我想我以前只是运气好。
一旦我在新集群上导入了我的 python 模块,python 就会出现段错误。Python 甚至没有从导入步骤中恢复过来。使用gdb
,我将其追踪到代码的另一部分,其初始化调用了一个Factorial
仿函数。但是FactorialTable
还没有初始化,所以整个事情都呱呱叫了。
所以我需要确保在计算其他代码之前计算我的阶乘。我以所需的顺序告诉 distutils,但显然这不是他们在此集群上调用的顺序。链接过程中是否有一些我需要小心的阶段?
如果你真的有动力,你可以在这里和这里浏览代码,以及在这里给出段错误的那一行。