短縮版
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 に希望する順序で伝えますが、明らかに、これはこのクラスターで呼び出される順序ではありません。リンク プロセスで注意が必要な段階はありますか?