[Python] Does Python allow defining a C function that a shared library can call directly?

Discussão em 'Python' iniciado por Stack, Outubro 6, 2024.

  1. Stack

    Stack Membro Participativo

    I figured out how to let Python call a function from my shared library:

    import ctypes

    def bar():
    return 1337

    dll = ctypes.PyDLL("./mod.so")

    assert dll.foo(ctypes.c_float(42)) == 42 + 1337


    where mod.so can call that bar Python function like so in C:

    int foo(float f) {
    PyObject *module = PyImport_ImportModule("main");
    PyObject *bar = PyObject_GetAttrString(module, "bar");
    PyObject *args = PyTuple_Pack(0);
    PyObject *result = PyObject_CallObject(bar, args);
    return f + PyLong_AsInt(result);
    }


    I'm essentially looking for a way to let the C foo() function call a function in the Python code directly, without needing anything Python specific like PyObject_CallObject(). This is what I'm trying to turn the C file into:

    int foo(float f) {
    return f + bar();
    }

    Context


    My programming language (see my blog post) its compiler+linker outputs a generic mod.so that is supposed to be usable by any programming language, so not just Python.

    This mod.so works out-of-the-box for C and C++, because the shared library simply uses a call instruction to call the main executable's bar function. Python (and most other high-level languages) on the other hand don't allow you to call a Python function like this directly. This makes sense, as Python wraps primitive C types in custom structs. This is why we needed the PyObject_CallObject() call in the above code.

    I could write a program that replaces all of the call instructions with the chain of PyImport_ImportModule() + PyObject_GetAttrString() + etc. calls, but I'd prefer leaving the mod.so alone for technical reasons.

    What I got working is putting an adapter.c as a middleman between the Python code and the mod.so. adapter.so just exists to expose a bar wrapper function that mod.so can call directly, containing the PyObject_CallObject and co. calls. See my previous Stack Overflow question for the rough code.

    Because my programming language already requires the game developer to document the mod API in mod_api.json, it is possible to regenerate this adapter.c file automatically, but ideally this step wouldn't be required at all.

    Looping back to the post's title


    Does Python allow defining a C function that a shared library can call directly? If so, then I wouldn't have to worry about modifying mod.so nor having an adapter.c. Thanks.

    Continue reading...

Compartilhe esta Página