在初始化嵌入式Python时,在运行时创建Python3模块

时间:2013-08-07 15:43:26

标签: c++ python embedding extending

我们有一个实现自定义编程语言的DLL。我想要做的是添加对python语言的支持,为“API函数”保留相同的代码。

我已经在这个DLL中成功嵌入了python,现在我正在接近将所有旧函数作为python模块公开的问题。

现在这个DLL没有将API函数公开为接口函数,但它已经安装(作为函数指针)到语言引擎。这样就不可能创建一个新的python模块(一个新的DLL)。但我需要保持与旧方法的兼容性......

可以在运行时创建(并安装)在Python所在的同一DLL中定义的模块吗?

我觉得像在PyInitialize();

之后调用PyInit_xxxx方法

3 个答案:

答案 0 :(得分:1)

我已经解决了使用类似之前的代码 Py_Initialize();

/* Add a built-in module, before Py_Initialize */
PyImport_AppendInittab("xxx", PyInit_xxx);

答案 1 :(得分:1)

处理此问题的最简单方法是在调用Py_Initialize()或PyMac_Initialize()之后直接调用initspam()来静态初始化静态链接的模块:

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();

可以在Python源代码分发中的Demo / embed / demo.c文件中找到一个示例。

答案 2 :(得分:1)

这在Python 3中已经变得非常复杂了(与Python 2中的相比),但我已经让它适用于我的代码,所以我希望这也适合你。

// Python 3's init function must return the module's PyObject* made 
// with PyModule_Create()
PyObject* initspam(); 
const char* spam_module_name;

int main(int argc, char **argv)
{
    Py_Initialize();

    PyImport_AddModule(spam_module_name);
    PyObject* module = initspam();

    PyObject* sys_modules = PyImport_GetModuleDict();
    PyDict_SetItemString(sys_modules, spam_module_name, module);
    Py_DECREF(module)

    ...
}

我在python 3源代码中找到了一个这样的例子:

  

Python-3.4.2 \ Python \ pythonrun.c:import_init()

这比我上面的例子有更好的错误检查。