Итак, StackOverflow, я в тупике.
Код, который у меня есть, это функция C ++ со встроенным Python. Я генерирую сообщение на стороне C ++, отправляю его на python, получаю другое сообщение обратно. Я заставил это работать, я проверил это, пока все хорошо.
Следующим шагом является то, что мне нужен Python, чтобы генерировать сообщения самостоятельно и отправлять их в C ++. Вот где я начинаю застрять. Потратив несколько часов на размышления над документацией, казалось, что лучшим способом было бы определить модуль для хранения моих функций. Поэтому я написал следующую заглушку:
static PyMethodDef mailbox_methods[] = {
{ "send_external_message",
[](PyObject *caller, PyObject *args) -> PyObject *
{
classname *interface = (classname *)
PyCapsule_GetPointer(PyTuple_GetItem(args, 0), "turkey");
class_field_type toReturn;
toReturn = class_field_type.python2cpp(PyTuple_GetItem(args, 1));
interface ->send_message(toReturn);
Py_INCREF(Py_None);
return Py_None;
},
METH_VARARGS,
"documentation" },
{ NULL, NULL, 0, NULL }
};
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
"turkey",
"documentation",
-1,
mailbox_methods
};
//defined in header file, just noting its existence here
PyObject *Module;
PyMODINIT_FUNC PyInit_turkey()
{
Module = PyModule_Create(&moduledef);
return Module;
}
А на стороне Python у меня был следующий код получателя:
import turkey
Я получаю следующий ответ:
ImportError: No module named 'turkey'
Теперь вот часть, где я действительно запутался. Вот код в моей функции инициализации:
PyInit_turkey();
PyObject *interface = PyCapsule_New(this, "instance", NULL);
char *repr = PyUnicode_AsUTF8(PyObject_Repr(Module));
cout << "REPR: " << repr << "\n";
if (PyErr_Occurred())
PyErr_Print();
Распечатывает
REPR: <module 'turkey'>
Traceback (most recent call last):
<snipped>
import turkey
ImportError: No module named 'turkey'
Итак, модуль существует, но его нигде не передают в Python. Я не могу найти документацию о том, как передать его и инициализировать на стороне Python. Я понимаю, что, возможно, я просто пропускаю тривиальный шаг, но я не могу всю жизнь понять, что это такое. Кто-нибудь может помочь?
Ответ был, в конце концов, единственной функцией, которую мне не хватало. Включено в начале моей функции инициализации, прежде чем я вызову Py_Initialize:
PyImport_AppendInittab("facade", initfunc);
Py_Initialize();
PyEval_InitThreads();
Документация Python не упоминает PyImport_AppendInittab, за исключением случаев прохождения, и именно поэтому у меня было такое трудное время для прыжка.
Для тех, кто найдет это в будущем: вам не нужно создавать DLL для расширения Python или использовать предварительно собранную библиотеку для переноса модуля в Python. Это может быть намного проще, чем это.
Других решений пока нет …