何か「ハリーポッターと魔法のナントカ」みたいなタイトル…
それはともかくSWIGとnumpyでハマってしまったので備忘録的にメモ。
現象としては
- hppでNO_IMPORT_ARRAYを定義して#include <numpy/arrayobject.h>すると、.pyファイルでSWIGモジュールをインポートした時点でimporterror (undefined symbol: PyArray_API)が起きる。
- NO_IMPORT_ARRAYを定義しないと、 cppでPyArray_ZEROS()を呼んだところでセグフォが起きる。
苦しんだのですが調べていてようやくわかりました。 基本的に
PY_ARRAY_UNIQUE_SYMBOL
が必要。
- .iファイルのinit節でimport_array();呼び出し
%init %{ import_array(); %}
- PY_ARRAY_UNIQUE_SYMBOLをdefineする共通のヘッダファイルを作成
#ifndef COMMON_HPP #define COMMON_HPP #define PY_ARRAY_UNIQUE_SYMBOL mytest_array_API #endif
(↑基本的にmypaintのcommon.hppのパクリ)
- このcommon.hppを、すべてのヘッダファイルで#include
- ラッパー用ヘッダでのみNO_IMPORT_ARRAYを定義せず、その他の自作ヘッダではすべて#include <numpy/arrayobject.h>前にNO_IMPORT_ARRAYをdefineする。
- NO_IMPORT_ARRAYを定義せずに#include “common.hpp"してあると、その都度シンボルが作られるらしくビルドエラーになる
これで、ImportErrorもビルドエラーもセグフォも起きなくなりました。
ところで統合開発環境のPyCharmを試してみたのですがこれは凄いですね。MyPaintも楽々走るしブレークポイントも普通に置けて(当然か…)これヤバイよ!と思いましたが、唯一悲しいのが起動速度の遅さ…まぁ、いいか。まだ、あんまり使ってないのですが。 ああ、あとちょっともっさり気味かもですが、これはまぁ機能の高さとおそらくpythonで書かれてる点からして仕方ないかも。