PyBindGen のドキュメントによると、独自のデータ型のカスタム型ハンドラーを簡単に作成できます。しかし、それらを書いた良い例は見つかりませんでした。pybindgen で提供される例は、詳細を理解するにはあまりにも基本的であり、ドキュメントは残念ながらほとんど存在しません。私が正確に必要とするのは:
- コンバーターのベースとしてどのクラスを使用する必要がありますか?
- バインディング コードの特定の部分を拡張または置換するには、どのメソッドをオーバーロードする必要がありますか?
- const パラメータと非 const パラメータを処理するには、どのようなアプローチを使用すればよいですか?
カスタムタイプハンドラをpybindgenに追加する完全で十分に文書化された例はありますか? 誰かがあなた自身のプロジェクトでこれを行い、アプローチを共有するかもしれませんか?
必要なものをよりよく理解するための現在のバインディングの例。現在Boost.pythonで完了:
PyObject* System_getXYZ(System* s, int ind, int fr){
CREATE_PYARRAY_1D(p,3)
MAP_EIGEN_TO_PYARRAY(v,Vector3f,p)
v = s->XYZ(ind,fr);
return boost::python::incref(p);
}
...
class_<System, boost::noncopyable>("System", init<>())
...
.def("getXYZ", &System_getXYZ)
...
;
メソッド System::XYZ() は Eigen::Vector3f オブジェクトを返します。データをコピーせずにnumpy配列に変換する必要があります。全体のアイデアは効率に関するものであるため、これは重要です。現在、それは醜いマクロによって行われています:
#define MAP_EIGEN_TO_PYARRAY(_matr,_T,_obj_ptr) \
if(!PyArray_Check(_obj_ptr)) throw pteros::Pteros_error("NumPy array expected!"); \
if(PyArray_TYPE(_obj_ptr)!=PyArray_FLOAT) throw pteros::Pteros_error("float NumPy array expected!"); \
Eigen::Map<_T> _matr((float*) PyArray_DATA(_obj_ptr), \
(PyArray_DIM((PyArrayObject*)_obj_ptr,0)==PyArray_Size(_obj_ptr)) ? PyArray_DIM(
(PyArray_DIM((PyArrayObject*)_obj_ptr,0)==PyArray_Size(_obj_ptr)) ? 1 : PyArray_
#define CREATE_PYARRAY_1D(_ptr_obj, _dim1) \
PyObject* _ptr_obj; \
{ \
npy_intp _sz_dim1[1];\
_sz_dim1[0] = _dim1; \
_ptr_obj = PyArray_SimpleNew(1, _sz_dim1, PyArray_FLOAT); \
}
これは機能しますが、Eigen オブジェクトを使用するメソッドごとにラッパー関数を作成する必要があり、これを維持するのは悪夢です。そのため、PyBindGen を試して、これらのマクロからすべてのボイラープレート コードを自動的に追加するコンバーターを作成したいと考えています。
ところで、boost.python コンバーターはデータのコピーを強制するため、ここでは役に立ちません。