1. ホーム
  2. python

[解決済み】「Symbol not found / Expected in: flat namespace」は実際にはどういう意味ですか?

2022-02-09 04:28:39

質問

ビルドしたモジュールをインポートすると、このようなboost-python関連のエラーが発生します。

Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: dlopen(./myMod.so, 2): Symbol not found: __ZN5boost6python7objects15function_objectERKNS1_11py_functionERKSt4pairIPKNS0_6detail7keywordES9_E
  Referenced from: ./myMod.so
  Expected in: flat namespace
 in ./myMod.so

これは実際にはどういうことなのでしょうか?なぜこのエラーが発生したのでしょうか?

解決方法は?

説明

でコンパイルされたオブジェクトが混在しているために発生した問題です。 libc++ でコンパイルされたオブジェクトと libstdc++ .

この場合、ライブラリ myMod.so (でコンパイルされている)。 libstdc++ ) が必要です。 boost-python でコンパイルしたものを libstdc++ ( boost-python-libstdc++ を追加しました。) いつ boost-pythonboost-python-libstdc++ であれば、問題なく動作します。そうでない場合は、コンピュータ上で boost-python でコンパイルしています。 libc++ (または他の c++ ライブラリ) を読み込んで実行する際に問題が発生します。

私たちの場合、この現象は libc++ の開発者が意図的にすべてのシンボルの名前を変えたのは、彼らのライブラリのコードと別のライブラリのコードが混在するのを防ぐため(そしてあなたを救うため)です。 myMod.so は、型から引数を取る関数が必要です。で libc++ この型の名前は std::__1::pair . したがって、このシンボルは見つかりませんでした。

同じAPIの2つのバージョンを混ぜることがなぜ悪いのかを理解するために、次のような状況を考えてみましょう。2つのライブラリがある。 FooBar . どちらも std::string を使い、それを何かに利用するのですが、両者は異なるc++ライブラリを使っています。しかし、両者は異なるC++ライブラリを使用しています。 std::string で作成されたものを Foo に渡されます。 Bar , Bar は、これがその c++ ライブラリの std::string で、悪いことが起こる可能性があります(両者は全く別のオブジェクトです)。

備考 : 場合によっては、同じAPIの異なるバージョンが2つ以上、プログラムの全く別の部分に存在しても問題はないでしょう。しかし、そのAPIのオブジェクトをプログラム間で受け渡しする場合は問題があります。特に、APIオブジェクトを他のオブジェクトのメンバとしてしか渡さない場合、その確認は非常に困難です。また、ライブラリの初期化関数は、2度起こってはいけないことをすることがある。別のバージョンでは、これらのことが再び行われるかもしれません。

それを解決するには?

  • ライブラリはいつでも再コンパイルして、互いに一致させることができます。

  • をリンクすることができます。 boost-python をスタティック・ライブラリとして使用することができます。そうすれば、ほとんどすべてのコンピュータで動作します。 boost-python がインストールされている)。もっと詳しく見る こちら .

概要

myMod.so の別バージョンが必要です。 boost-python 特定の c++ ライブラリでコンパイルされたものです。そのため、他のバージョンでは動作しません。