2011-03-30 5 views
1

Python xmlrpc 클라이언트를 만들고 xmlrpc 서버에서 메서드를 호출하는 C 코드를 만들려고합니다 (이 코드를 후크 DLL에 대해 IPC로 사용하려고합니다).xmlrpc를 통해 파이썬 원격 프로 시저 호출을 시도하는 C 코드가 충돌합니다.

코드는 다음과 같습니다. 작동 될 때까지 참조 계산에 레이어하지 않을 것입니다.

#include <Python.h> 
#define WIN32_LEAN_AND_MEAN 
#include <Windows.h> 

static PyObject *xmlrpc_server_proxy = NULL; 
static PyObject *set_server_proxy(void); 
static void say_hi(void); 

int main() 
{ 
    xmlrpc_server_proxy = set_server_proxy(); 
    say_hi(); 
    return 0; 
} 

static PyObject * 
set_server_proxy() 
{ 
     PyObject *xmlrpc_client_mod, *xmlrpc_server_proxy_class, *location, *args; 
     PyObject *result; 
     Py_Initialize(); 
     xmlrpc_client_mod = PyImport_ImportModule("xmlrpc.client"); 
     xmlrpc_server_proxy_class = PyObject_GetAttrString(xmlrpc_client_mod, "ServerProxy"); 
     location = PyUnicode_FromString("http://127.0.0.1:8000/"); 
     args = Py_BuildValue("(O)", location); 
     result = PyObject_CallObject(xmlrpc_server_proxy_class, args); 
     Py_Finalize(); 
     return result; 
} 

static void say_hi() 
{ 
    PyObject_CallMethod(xmlrpc_server_proxy, "say_hi", "()"); 
} 

다른 Python 서버 프록시에서 호출 할 때 내 Python xmlrpc 서버가 제대로 작동하는지 확인했습니다. 위의 실행 파일을 실행하려고하면 PyObject_CallMethod()에서 충돌합니다. 왜?

+0

내 초기 본능 : 파이썬의 당신이 당신의 수입을 변경해야 할 수도 있습니다 xmlrpclib.ServerProxy 표준을 사용하려는 경우,

int main() { Py_Initialize(); xmlrpc_server_proxy = set_server_proxy(); say_hi(); Py_Finalize(); return 0; } 

둘째로 :

main() 기능을 내부에 통역 초기화 호출을 이동

PyObject_CallObject()이거나 set_server_proxy()의 Py * 함수 중 하나가 호출이 NULL을 반환하고 있다는 것입니다. 각 Py * 함수의 반환을 확인하여 함수를 잘못 호출하는 것에 대한 통찰력을 줄 수 있으므로 NULL을 반환하는 것이 무엇인지 확인해야합니다. – Suroot

답변

1

set_server_proxy() 끝 부분에있는 사용자는 Py_Finalize()을 호출하여 인터프리터를 파괴합니다. 그런 다음 계속 인터프리터가 있다고 가정하여 say_hi()을 호출하고 있습니다. 파이썬 인터프리터 코드가 에러를 발생 시키려고 할 때, PyErr_Occurred() 함수는 현재 쓰레드 상태에 대한 포인터를 얻는다. 이것은 NULL이다; 그것을 역 참조하고 이것이 segfault를 생성합니다.

xmlrpc_client_mod = PyImport_ImportModule("xmlrpclib"); 
+0

인터프리터가 사라진 후에 인터프리터를 사용하여 파이썬 객체를 만들 수있는 또 다른 방법이 있습니까? 이 DLL이 후크 DLL에서 구현된다는 것을 감안할 때 Py_Initialize를 호출 된 함수에서 이동할 수 있는지 확신 할 수 없습니다 (Dllmain에 들어갈 수 없다면). – MikeRand

+0

대다수의 경우에는 가능하지 않을 수도 있습니다 (일부 경우). 'PyObject_CallMethod'는 인터프리터 상태에 직접 의존하는 다른 함수를 내부적으로 호출합니다. 아마도 인터프리터의 수명을 DllMain'DLL_PROCESS_ATTACH/DLL_PROCESS_DETACH' 이벤트에 연결할 수 있습니까? – samplebias

+0

Py_Initialize와 set_server_proxy()를 모두 DLL_PROCESS_ATTACH로 옮기고 Py_Finalize를 DLL_PROCESS_DETACH로 옮겼습니다 ... xmlrpc를 사용하여 UAC를 다루지 않고 Vista Windows API 호출을 모니터링합니다. 도와 주셔서 감사합니다. – MikeRand