Kentzo
Kentzo

Reputation: 3981

How to load a C extension from C

I have an embedded version of Python (2.7 and 3.x) with very special module finder and loader. These finder and loader are written in C and must be able to load a C-extension module by name and associate it with fqmn.

While it's pretty straightforward of how to manually load pure python module (open file, read data, exec) I cannot find how to do this with C-extensions.

Is there an example or some opensource project that demonstrates it?

Upvotes: 1

Views: 83

Answers (1)

Kentzo
Kentzo

Reputation: 3981

The imp module did it:

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;
}

Upvotes: 1

Related Questions