在 C 中导入 Python 模块

Importing a Python module in C

我正在尝试将一些 Python 2 代码移植到 Python 3。在代码中有一个在 C 部分初始化的模块,稍后由 python 代码。但是我的 python 代码没有看到用 C 初始化的模块。这是一个简化的例子:

#include <Python.h>
#include <stdio.h>

static PyMethodDef BenchMethods[] = {
        {NULL, NULL, 0, NULL}
};

int main(int argc, char **argv)
{
        PyObject *module;

        Py_SetProgramName(argv[0]);
        Py_Initialize();

        static struct PyModuleDef benchdef = {
                PyModuleDef_HEAD_INIT,
                "bench",
                NULL,
                -1,
                BenchMethods,
                NULL,
                NULL,
                NULL,
                NULL,
        };
        module = PyModule_Create(&benchdef);
        if (module == NULL) {
                printf("ERROR!\n");
                exit(0);
        }
        PyRun_SimpleString("import bench");

        Py_Finalize();
        return 0;
}

但是在编译并尝试执行它时我得到一个错误:

$ gcc -I/path/to/include/python3.9 -o bench_simple.x bench_simple.c -L/path/to/lib -lpython3.9
$ ./bench_simple.x 
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'bench'

在Python 2 版本中,模块通过module = Py_InitModule("bench", BenchMethods); 初始化。我根据找到的说明移植了代码 here

PyModule_Create()(成功时)创建一个模块对象。它不会将该对象加载到任何解释器中,并且已创建模块对象的事实不会自动将其放入任何解释器的模块加载路径中。这就是示例程序中 import bench 失败的原因。

Python C API 文档给出了具体的 instructions,并提供了示例支持,说明嵌入 python 的应用程序如何以编程方式定义模块并嵌入解释器加载它。简而言之,关键是您的应用程序不能直接调用 PyModule_Create(),而必须

  1. 定义一个模块初始化函数来进行调用和 returns 结果,
  2. 在初始化解释器之前,调用 PyImport_AppendInittab() 将该初始化函数注册到所选模块名称。