ソフトウェア開発者の日常

こだわりなく書きたいことを書いていきます。

boost.pythonを使ったC++で書かれた共有ライブラリをimportするとエラーが発生する

PythonとC(C++)の連携をしたくて、こちらのページのsimple.cxxのサンプルを試しに入力してコンパイルしました。
c/c++をラップしてpythonで使えるように - Python | Welcome to underground

環境は、
Ubuntu 16.04.3
Python 2.7.12
gcc 5.4.0
という、Ubuntuインストールしてアップデートしたら出来あがった環境です。
コンパイルのパラメータに

/usr/include/python2.6

とあったので、python2.7ディレクトリがあるか確認するとありませんでした。
調べた結果、

$ sudo apt-get install libboost-all-dev

でインストールしたら、/usr/include/python2.7が作成されました。

コンパイルは、上記のページを参考に

$ g++ -fPIC -Wall -O2 -I/usr/include/python2.7 -lboost_python -shared -o simple.so simple.cxx

で行いました。

コンパイルが終わったので、Pythonから試してみたところ

>>> import simple
Traceback (most recent call last):File "<stdin>", line 1, in <module>
ImportError: ./simple.so: undefined symbol: _ZTIN5boost6python7objects21py_function_impl_baseE

とエラーが表示されました。

f:id:AJYA:20170913232139j:plain
photo credit: photogenicgreen.nl Jul09_volunteers_015_APeviani via photopin (license)

コンパイル時のオプションの順序が影響

stdinなんて、なぜ表示されるんだ?と思いながら検索をすると、こちらのページに辿り着きました。
t.co
こちらのページの回答3に、

importance of the position of "-lpython2.6 -lboost_python"

とありました。
コンパイルのオプションの順番が重要なようです。
試しに、

g++ -fPIC -Wall -O2 -shared -o simple.so simple.cxx -I/usr/include/python2.7 -lboost_python

コンパイルして再度Pythonから試したところ、エラーは発生しなくなりました。

この後別のサイトのサンプルなどのコンパイルでも、上記の順序で指定してコンパイルしていれば、エラーは発生しませんでした。