そのため、Pythonのカスタムタイプ、関数、属性で問題が発生しています。
Pythonを使用していて、カスタムタイプの1つ(Vector4など)に属性を設定したい場合、コードはconst char* attribute_name
引数に対してNULLを取得します(はい、モジュールをインポートしています)。
奇妙なことに、setter関数で属性名をハードコーディングすると、次のエラーが発生します。
SystemError: error return without exception set
オブジェクトがPython(およびC ++)で作成されているのを確認しているので、それが問題になるとは思いません。setattroフックがC++で属性を正常に設定した場合は、1を返します。コードが呼び出され、C++側で属性が設定されているのがわかります。属性が設定されているときに発生するエラー/例外はありません。
さらに、Pythonでクラスのインスタンスで関数を呼び出すとtp_getattro
、辞書をチェックする代わりに、で設定された関数が呼び出されます。
理由はよくわかりません。配列を介して行うのではなく、辞書を設定して関数を配置しているため、が呼び出されたPyModuleDef
ときに関数が表示されないためです。PyType_Ready
なぜこれが起こっているのか誰かが知っていますか?Python3.2を使用しています。
関連する:
基本型(tp_new
およびtp_dealloc
)があり、実行時に派生型を作成しています。派生型には、ディクショナリ、、、tp_base
およびtp_getattro
がありtp_setattro
ます。
これは、関数がPythonクラス/タイプにバインドされる方法です。
PyMethodDef newMethod;
newMethod.ml_doc = newMethod.ml_name = funcName;
newMethod.ml_flags = METH_VARARGS;
newMethod.ml_meth = pythonFunc;
PyGeneralObj* selfFake = PyObject_New(PyGeneralObj, &MetaEngineType);
selfFake->className = className;
selfFake->funcName = funcName;
Py_INCREF((PyObject*)selfFake);
PyObject *func = PyCFunction_New(&newMethod, (PyObject*)selfFake);
PyObject *method = PyInstanceMethod_New(func);
ErrorIf((method == NULL), "Python: Cannot create instance function. %s",
funcName);
ErrorIf((PyDict_SetItem(classObj->m_pyClassType->tp_dict,
PyReturnStr(newMethod.ml_name), method) == -1),
"Python: Cannot create function in dictionary.");
Py_DECREF(func);
Py_DECREF(method);
ここで、funcNameとclassNameはconstchar*です。pythonFuncは、メタシステムにバインドされているすべての関数の呼び出しを処理する汎用のPython関数です。classObjは、メンバーm_pyClassType(PyTypeObjectのタイプ)を持つPythonClassへのポインターです。
PyGeneralObj
新しいオブジェクトは2つのconstchar*とvoid*を持っています(これはC ++のオブジェクトです)
エラーは発生せPyType_Ready
ず、タイプをインクリメントします。次に、から与えられたモジュールPyObjectにオブジェクトを追加しますPyImport_ImportModule
。メインモジュールをランタイムに追加し、Pythonを初期化して、モジュールをインポートします。
より多くの情報/コードが必要な場合は、もう少し投稿できます。これが理にかなっていることを願っています。stackoverflowに投稿するのはこれが初めてです。
明確にするために、C++側で完全に解決される動的属性が必要です。PyObject* self
また、関数の場合、呼び出す必要のある関数の文字列名を取得できるように、引数をオーバーライドできるようにしたいと思います。
Boost、Cythonなどのサードパーティのライブラリ/インターフェースは使用したくありません。