Сбой кода C при попытке вызова удаленной процедуры Python через xmlrpc

1

Я пытаюсь создать C-код, который создает клиент Python xmlrpc и вызывает методы на сервере xmlrpc (я думаю об использовании этого как IPC для DLL-подключения).

Вот код... Я не собираюсь выравнивать счетчик ссылок до тех пор, пока он не будет работать.

#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 xmlrpc отлично работает при вызове с другого прокси-сервера Python. Когда я пытаюсь запустить вышеуказанный исполняемый файл, он падает на PyObject_CallMethod(). Почему?

  • 0
    Мой первоначальный инстинкт состоит в том, что PyObject_CallObject () или одна из функций Py * в set_server_proxy (), вызываемая, возвращает NULL. Вы должны проверить возвращение каждой из функций Py *, чтобы увидеть, что возвращает NULL, поскольку это может дать представление о неправильном вызове функции.
Теги:
python-extensions

1 ответ

1
Лучший ответ

В конце set_server_proxy() вы вызываете Py_Finalize(), который уничтожает интерпретатор, а затем вы вызываете say_hi(), который предполагает, что интерпретатор все еще существует. Когда код Python interprer пытается поднять ошибку, функция PyErr_Occurred() получает указатель на текущее состояние потока, которое равно NULL; он разыгрывает его, и это генерирует segfault.

Переместите вызовы инициализации интерпретатора внутри функции main():

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

Во-вторых, если вы пытаетесь использовать стандарт Python xmlrpclib.ServerProxy, вам может потребоваться изменить свой импорт:

xmlrpc_client_mod = PyImport_ImportModule("xmlrpclib");
  • 0
    Есть ли другой способ использовать интерпретатор для создания объекта Python, который остается после того, как интерпретатор ушел? Учитывая, что это будет реализовано в подключаемой DLL, я не уверен, что смогу переместить Py_Initialize из вызываемой функции (если только он не может идти в Dllmain, чего я не уверен).
  • 0
    Я не думаю, что это возможно в подавляющем большинстве случаев (может быть, в некоторых крайних случаях). PyObject_CallMethod внутренне выполняет вызовы других функций, которые напрямую зависят от состояния интерпретатора. Возможно, вы можете связать срок службы переводчика с событиями DLL_PROCESS_ATTACH / DLL_PROCESS_DETACH ?
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню