如何从C加载C扩展

时间:2014-11-04 02:10:38

标签: python-2.7 python-3.x

我有一个嵌入式版本的Python(2.7和3.x),带有非常特殊的模块查找器和加载器。这些查找程序和加载程序是用C语言编写的,必须能够按名称加载C扩展模块并将其与fqmn关联。

虽然如何手动加载纯python模块(打开文件,读取数据,exec)非常简单,但我找不到如何使用C扩展来实现这一点。

是否有一个示例或一些开源项目来演示它?

1 个答案:

答案 0 :(得分:1)

imp模块做到了:

PyObject* load_c_extension(const char *fqmn, const char *filepath)
{
    static PyObject *load_module = NULL;
    static PyObject *open_file = NULL;

    if (!load_module)
    {
        PyObject *imp_module = PyImport_ImportModule("imp");
        if (!imp_module)
            return NULL;

        load_module = PyObject_GetAttrString(imp_module, "load_module");
        Py_DECREF(imp_module);

        if (!load_module)
            return NULL;
    }

    if (!open_file)
    {
        PyObject *builtins = PyEval_GetBuiltins();
        if (!builtins)
            return NULL;

        open_file = PyDict_GetItemString(builtins, "open");
        if (!open_file)
            return NULL;
    }

    PyObject *module_file = PyObject_CallFunction(open_file, "ss", filename, "rb");
    if (!module_file)
        return NULL;

#if defined(_WIN32)
    PyObject *module = PyObject_CallFunction(load_module, "sOs(ssi)", fqmn, module_file, filename, ".pyd", "rb", 3);
#else
    PyObject *module = PyObject_CallFunction(load_module, "sOs(ssi)", fqmn, module_file, filename, ".so", "rb", 3);
#endif
    Py_DECREF(module_file);

    if (!module)
        return NULL;

    return module;
}