@@ -52,16 +52,29 @@ PyObject* CppObjectMapper::CreateFunction(pesapi_callback Callback, void* Data,
5252 // 不能用栈变量
5353 PyMethodDef* methodDef = (PyMethodDef*) PyMem_Malloc (sizeof (PyMethodDef));
5454 methodDef->ml_name =" PapiCallback" ;
55- methodDef->ml_meth = [](PyObject* self, PyObject* args) -> PyObject*
55+ methodDef->ml_meth = (PyCFunction)(PyCFunctionWithKeywords) [](PyObject* self, PyObject* args, PyObject *kwargs ) -> PyObject*
5656 {
5757 FuncInfo* data = reinterpret_cast <FuncInfo*>(PyCapsule_GetPointer (self, " FuncInfo" ));
5858 if (!data || !data->callback )
5959 {
6060 PyErr_SetString (PyExc_RuntimeError, " Invalid callback data" );
6161 return nullptr ;
6262 }
63+
64+ // When we need to call the callback with custom self
65+ // foo(.., this: DynObj)
66+ void * selfPtr = nullptr ;
67+ if (kwargs && PyDict_Check (kwargs)) {
68+ auto kw_self = PyDict_GetItemString (kwargs, " this" );
69+ if (kw_self && Py_TYPE (kw_self)->tp_basicsize == sizeof (DynObj) && PyObject_HasAttrString ((PyObject*)Py_TYPE (kw_self), CTX_ATTR_NAME))
70+ {
71+ auto DynSelf = (DynObj*) kw_self;
72+ selfPtr = DynSelf->objectPtr ;
73+ }
74+ }
75+
6376 pesapi_callback_info__ callbackInfo;
64- callbackInfo.self = nullptr ;
77+ callbackInfo.self = selfPtr ;
6578 callbackInfo.selfTypeId = nullptr ;
6679 callbackInfo.args = args;
6780 callbackInfo.argc = static_cast <int >(PyTuple_Size (args));
@@ -93,7 +106,7 @@ PyObject* CppObjectMapper::CreateFunction(pesapi_callback Callback, void* Data,
93106
94107 Py_RETURN_NONE;
95108 };
96- methodDef->ml_flags = METH_VARARGS;
109+ methodDef->ml_flags = METH_VARARGS | METH_KEYWORDS ;
97110 methodDef->ml_doc = " Puerts C++ callback wrapper" ;
98111 data->methodDef = methodDef;
99112
0 commit comments