Dov Grobgeld
Dov Grobgeld

Reputation: 4983

In pybind11, how do you make a py::module known for import?

In an embedded C++ program in pybind11, I'm defining a python module to use as a container for multiple python objects that I don't want to expose to the global namespace. I then want import this module as needed. But it appears that just defining a module through py::module('mymodule') isn't enough.

The following sample code compiles without problems but terminates with the run time error "No module named 'application'". So how do I make the "application" module known to python?

#include <pybind11/embed.h>

namespace py = pybind11;

int main(int argc, char *argv[])
{
    py::scoped_interpreter guard{};

    // Construct python wrappers for them
    py::module m("application");

    // Define some objects in the module
    m.add_object("pet", py::cast("dog"));

    // Import the module and access its objects
    py::exec("import application\n"
             "print(application.pet)");
}

Upvotes: 1

Views: 2960

Answers (1)

Sergei
Sergei

Reputation: 1789

Pybind defines PYBIND11_EMBEDDED_MODULE macro to create embedded modules.

https://pybind11.readthedocs.io/en/stable/advanced/embedding.html#adding-embedded-modules

#include <pybind11/embed.h>
namespace py = pybind11;

PYBIND11_EMBEDDED_MODULE(fast_calc, m) {
    // `m` is a `py::module` which is used to bind functions and classes
    m.def("add", [](int i, int j) {
        return i + j;
    });
}

int main() {
    py::scoped_interpreter guard{};

    auto fast_calc = py::module::import("fast_calc");
    auto result = fast_calc.attr("add")(1, 2).cast<int>();
    assert(result == 3);
}

Upvotes: 1

Related Questions