Skip to content

Commit 6c84b16

Browse files
authored
python 支持以 method(this=DynObj) 的方式调用实例的泛型方法 (#2296)
* python CreateFunction 添加 this 关键字参数来传入self * python 支持以 method(this=DynObj) 的方式调用实例的泛型方法
1 parent b847924 commit 6c84b16

File tree

2 files changed

+19
-6
lines changed

2 files changed

+19
-6
lines changed

unity/native/papi-python/source/CppObjectMapperPython.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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

unity/test/Src/Cases/Python/CrossLang/GenericTest.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public void StaticGenericMethodTestOverloadPythonTest()
117117
pythonEnv.Dispose();
118118
}
119119

120-
/*[Test]
120+
[Test]
121121
public void InstanceGenericMethodPythonTest()
122122
{
123123
var pythonEnv = new ScriptEnv(new BackendPython());
@@ -128,12 +128,12 @@ public void InstanceGenericMethodPythonTest()
128128
testobj := GenericTestClass(),
129129
setattr(testobj, 'stringProp', 'world'),
130130
method := puerts.generic_method(GenericTestClass, 'InstanceGenericMethod', Int32),
131-
method(testobj)
131+
method(this=testobj)
132132
)[-1])()
133133
");
134134
Assert.AreEqual(result, "world_Int32");
135135
pythonEnv.Dispose();
136-
}*/
136+
}
137137

138138
[Test]
139139
public void GenericAccessPythonTest()

0 commit comments

Comments
 (0)