モブ沢工房

プログラミングとかLinux関連(特にOSSのグラフィックツール関連)とかレトロゲームとか3Dプリンタやら日曜大工等、色々。

SWIG & python でundefined_symbolが出る時

何か超久々ですがとりあえず… とりあえず以下、例として、

  • Flagtileというクラスがあるとします
  • python用のtestlib2モジュールに組み込まれます。
  • SWIG, g++ともコンパイルは問題なく通る
  • C++内では普通に使えている
  • しかし、SWIGPythonモジュールに組み込むと、そのモジュールのimportが通らない。
In [1]: import testlib2
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-1-e3832f46d55b> in <module>()
----> 1 import testlib2

/home/dothiko/python/test/mypainttest/fill_prog/testlib2.py in <module>()
     26                 fp.close()
     27             return _mod
---> 28     _testlib2 = swig_import_helper()
     29     del swig_import_helper
     30 else:

/home/dothiko/python/test/mypainttest/fill_prog/testlib2.py in swig_import_helper()
     22         if fp is not None:
     23             try:
---> 24                 _mod = imp.load_module('_testlib2', fp, pathname, description)
     25             finally:
     26                 fp.close()

ImportError: ./_testlib2.so: undefined symbol: _ZN9Flagtile25DIRTYE

こんなふうになる時ですね。

これは、私が経験した中では

  1. cppソースとhppで関数の引数が互換性があるが異なった型である (コンパイルエラーにならないので、見過ごしている)
  2. 「hppで宣言されているがcppに実体が存在しない」使用していない関数がある(警告を見過ごしている)
  3. SWIGが対応していない型を使っている

今回の場合は、SWIGが対応していない型、つまりFlagtile内にこのような宣言がある場合だったりしました。

    static const int32_t hogeflag = 0x00000001;

int32_tとかのなんて言うんでしょうか、正確にビットサイズを設定する型。これSWIGさんは嫌いらしいです。

ケツの座りは悪いですがintにすると通ります。*1 でも、intとかlongとか64ビットで何ビットだっけ?って考えるの嫌なんだよなぁ…

2018.9.10 追記

stackoverflow.com

SWIGのインターフェースファイル(.iファイル) で %import "stdint.i" とすれば良いようです!

ではでは!

*1:解決方法わかりました。追記見てください