irr::core::stringのラップ
Irrlichtはいい描画エンジンなのだが、なにもかもC++でやるとつらいのでスクリプト導入のターンとなるわけです。
そういうわけで、swigで半自動でCモジュールを作るのだがはまりポイントがある。
irr::core::stringであります。
以前、lua版作ったときも同じところではまった気がするが、今回はpython版。
以下、irrlichtのswigラップのirrString.hに関する部分を単体でビルドできるように試作したもの。
irr.i
%module "irr" %{ #include "Irrlicht.h" %} // pythonのunicodeをwchar_t*として受け取る %typemap(in) const wchar_t * const { $1 = PyUnicode_AS_UNICODE($input); } // irr::core::stringのコンストラクタがうまくいかないので生成用の関数 %inline %{ irr::core::stringc* strc(const char* const c){return new irr::core::stringc(c);} irr::core::stringw* strw(const wchar_t* const c){return new irr::core::stringw(c);} %} // swigで生成されるirr_wrap.cppのコンパイル通すのに必要 %{ using namespace irr; using namespace core; %} #pragma SWIG nowarn=362 #pragma SWIG nowarn=389 // コンパイル通すのに必要 // error: call of overloaded 'string(long int&)' is ambiguous ... %ignore irr::core::string::operator+=; %include "irrString.h" // テンプレート実体化 %template(irrStringC) irr::core::string<c8>; // Warning 490: Fragment 'SWIG_AsVal_wchar_t' not found // に対応。よくわからない // http://old.nabble.com/SWIG_AsVal_wchar_t-error-td4996377.html %fragment("SWIG_AsVal_wchar_t", "header", fragment="<wchar.h>") { SWIGINTERN int SWIG_AsVal_wchar_t(PyObject* p, wchar_t* c) { return SWIG_OK; } } %fragment("SWIG_From_wchar_t", "header", fragment="<wchar.h>") { SWIGINTERNINLINE PyObject* SWIG_From_wchar_t(wchar_t c) { return SWIG_Py_Void(); } } // テンプレート実体化 %template(irrStringW) irr::core::string<wchar_t>;
#!/usr/bin/env python """ setup.py file for SWIG example """ from distutils.core import setup, Extension module_name='irr' include_dirs=[ '/irrlicht/include', ] ex_module = Extension('_'+module_name, sources=[module_name+'.i'], swig_opts=['-I/irrlicht/include', '-c++'], include_dirs=include_dirs ) setup (name = module_name, version = '0.1', author = "ousttrue", description = """irrlicht string test""", ext_modules = [ex_module], py_modules = [module_name], )
ビルド
> python setup.py build_ext --inplace
動作確認
sample.py import irr print irr.strc("hoge") print irr.strw(u"hoge") <irr.irrStringC; proxy of <Swig Object of type 'irr::core::stringc *' at 0x00535CB0> > <irr.irrStringW; proxy of <Swig Object of type 'irr::core::string< wchar_t > *' at 0x00535CB0> >
あと、__str__を仕込めばよい感じになるんでないか。