【问题标题】:C++ static member initialization in python extension modulepython扩展模块中的C++静态成员初始化
【发布时间】: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,但显然这不是他们在此集群上调用的顺序。链接过程中是否有某个阶段需要我小心处理?

如果你真的有动力,你可以浏览代码herehere,以及给出段错误here的行。

【问题讨论】:

    标签: python c++ swig python-extensions


    【解决方案1】:

    没有可靠的方法来强制您的静态成员初始化的顺序。

    查看代码,但我认为您需要的不是 static 成员,而不是单例。 C++ 中的单例通常使用如下函数实现:

    FactorialFunctorData& _FactorialFunctorData()
    {
        static FactorialFunctorData data_;
        return data_;
    }
    

    这样你可以强制执行时间的顺序(通过按需要的顺序调用函数)。

    【讨论】:

      猜你喜欢
      • 2012-02-02
      • 2015-05-18
      • 2021-10-21
      • 2010-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多