Как добавить встроенный модуль в API C-Python после инициализации Py?
У меня есть модуль, определенный в моем C-коде следующим образом:
static struct PyModuleDef module_def = {
PyModuleDef_HEAD_INIT,
"the_module_name", /* m_name */
module_documentation, /* m_doc */
//....
};
И функция для его инициализации:
PyMODINIT_FUNC init_the_module(void)
{
PyObject *mod, *submodule;
PyObject *sys_modules = PyThreadState_GET()->interp->modules;
mod = PyModule_Create(&module_def);
PyModule_AddObject(mod, "some_submodule", (submodule = init_the_submodule()));
PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule);
Py_INCREF(submodule);
// more submodules..
return mod;
}
Приложение, в которое я встраиваю python, довольно большое, и я не могу сильно изменить рабочий процесс. В этот момент Py_Initialize
уже был вызван, поэтому я не могу вызвать PyImport_ExtendInittab
или PyImport_AppendInittab
.
Как я могу создать и добавить модуль в системные модули?
Может быть, я могу манипулировать словарем модулей напрямую? Вот так:
PyObject *modules, *the_module;
modules = PyImport_GetModuleDict();
PyDict_SetItemString(modules, "the_module_name", init_the_module());
the_module = PyDict_GetItemString(modules, "the_module_name"); //this is getting something back
std::cout << PyDict_Size(the_module) << std::endl; // this prints -1
1 ответ:
Самый простой способ справиться с этим-статически инициализировать статически связанные модули, непосредственно вызывая initspam () после вызова Py_Initialize () или PyMac_Initialize ():
int main(int argc, char **argv) { /* Pass argv[0] to the Python interpreter */ Py_SetProgramName(argv[0]); /* Initialize the Python interpreter. Required. */ Py_Initialize(); /* Add a static module */ initspam();
Пример можно найти в файле Demo/embed/demo.c в исходном дистрибутиве Python.