Py_InitModule
을 사용하여 콜백을 등록 할 때 나중에 구조의 함수 포인터를 새 함수를 가리 키도록 변경하면 새 함수가 호출됩니다. 그러나 이름을 변경하면 새 이름이 인식되지 않습니다.Py_InitModule은 함수 포인터가 아닌 이름을 복사합니까?
foo1 foo2 foo2 Traceback (most recent call last): File "", line 1, in AttributeError: 'module' object has no attribute 'foo2'
이것은 매우 모순 된 것 같다
#include <Python.h>
PyObject* foo1(PyObject *self, PyObject *args)
{
printf("foo1\n");
Py_RETURN_NONE;
}
PyObject* foo2(PyObject *self, PyObject *args)
{
printf("foo2\n");
Py_RETURN_NONE;
}
int main()
{
PyMethodDef methods[] = {
{ "foo", foo1, METH_VARARGS, "foo" },
{ 0, 0, 0, 0 }
};
Py_Initialize();
Py_InitModule("foo", methods);
PyRun_SimpleString("import foo\n");
PyRun_SimpleString("foo.foo()\n");
methods[0].ml_meth = foo2;
PyRun_SimpleString("foo.foo()\n");
methods[0].ml_name = "foo2";
PyRun_SimpleString("foo.foo()\n");
PyRun_SimpleString("foo.foo2()\n");
return 0;
}
이
다음과 같은 출력을 제공합니다. 변수가 범위를 벗어나고 여전히 파이썬에서 C++ 콜백을 호출하려고 시도한 후에 프로그램을 크래시 한PyMethodDef methods
에 스택 변수를 사용했을 때 처음 만났습니다. 그래서 포인터를 변경하면 실제로 다른
Py_InitModule
호출과 함께 다시 등록하지 않은 함수를 호출 변경합니다. 그러나 동시에 이름을 변경해도 이러한 동작이 발생하지 않습니다.
지금까지 나는 PyMethodDef
이 파이썬 코드가 메소드 (즉, 스택/로컬 변수가 될 수 없음)를 호출하려고하지만 함수 포인터 자체 만 사용되는 한 계속 살아야한다고 확신합니다.
의도적 인 행동입니까, 아니면 일부 감독입니까? 이 문서에는 찾을 수있는 PyMethodDef 수명에 대한 언급이 없습니다.
예상됩니다. 'PyInit_Module'이 아무것도 초기화하지 않았다고 생각 했습니까? 해석기에게 어떤 속성/메소드가 나중에 검사하지 않도록 정의되었는지 알려줍니다. 함수의 이름을 동적으로 바꾸려면 1) 인터프리터에서 모듈 객체를 가져와야합니다. 2) PyObject_SetAttr (또는 비슷한 이름으로 정확한 이름을 기억하지 못합니다)을 사용하여 모듈 객체의 속성을 설정합니다. – Bakuriu
@Bakuriu 감사합니다. 그러나 왜'ml_math' 필드도 복사되지 않았습니까? 즉, 나중에 함수를 변경하면 호출 할 함수를 핫 스왑하는 이유는 무엇입니까? – sashoalm