1

短縮版

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 が segfault を起こします。Python は、インポート ステップから戻ることさえありませんでした。を使用してgdb、これをコードの別の部分まで追跡し、その初期化でFactorialファンクターを呼び出しました。しかし、FactorialTableまだ初期化されていなかったので、全体が鳴きました。

したがって、他のコードが計算される前に階乗が計算されるようにする必要があります。distutils に希望する順序で伝えますが、明らかに、これはこのクラスターで呼び出される順序ではありません。リンク プロセスで注意が必要な段階はありますか?

本当にやる気がある場合は、ここここでコードを閲覧できます

4

1 に答える 1

2

静的メンバーが初期化される順序を強制する信頼できる方法はありません。

ただし、コードを見ると、必要なのはシングルトンではなく静的メンバーではないと思います。C++ のシングルトンは通常、次のような関数を使用して実装されます。

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

このようにして、実行時に順序を強制することができます (必要な順序で関数を呼び出すことによって)。

于 2014-04-20T05:43:05.113 に答える