Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Best way to combine two pybind11-wrapped projects #2056

Closed
lgritz opened this issue Jan 5, 2020 · 4 comments
Closed

Best way to combine two pybind11-wrapped projects #2056

lgritz opened this issue Jan 5, 2020 · 4 comments

Comments

@lgritz
Copy link

lgritz commented Jan 5, 2020

Please excuse me if an "issue" isn't quite the right place for this. Or if it's in the docs somewhere -- but I didn't see it.

Let's say I have project "A", which is a C++ library and pybind11-generated Python bindings for its major classes.

I also have project "B", another C++ library which has A as a dependency and in fact uses several classes of A in part of B's public APIs.

What is the best approach for adding pybind11-generated Python bindings to library B? Given that A has been built and has a Python module wrapping it, what do I have to do from B's side to not only add python bindings for B's classes, but also to incorporate A's classes into B's APIs, without duplicating the all the work done for the python bindings in A?

@lgritz
Copy link
Author

lgritz commented Jan 5, 2020

(Sorry if this looks like a duplicate. I accidentally submitted a half-written version, closed it, then tried again.)

@wjakob
Copy link
Member

wjakob commented Jan 5, 2020

Hi Larry, nice to see you here.

Basically everything should just work automatically, as long as the pybind11 extension libraries of the two different projects are compiled with the same compiler & version of STL. If a function in the python bindings of project "B" uses a type whose bindings are defined in project "A", you can import both bindings, instantiate via code in "A", and then call the python function from "B".

[FWIW In the upcoming Mitsuba 2, Enoki, NanoGUI, and several sub-components of Mitsuba 2 all exchange types in this way. It works robustly.]

If you don't want to force the user to import both modules, you can also do it manually in the binding code of project "B" and create aliases, e.g.

PYBIND11_MODULE(B, m) {
    py::module A = py::module::import("A");
    m.attr("some_function") = A.attr("some_function");
}

There is also this, which is worth looking at:
https://pybind11.readthedocs.io/en/master/advanced/misc.html#partitioning-code-over-multiple-extension-modules

@lgritz
Copy link
Author

lgritz commented Jan 5, 2020

Awesome, thanks! I didn't want to get too far down this rat hole only to find out it was impossible. Sorry I did not recognize that part of the docs as the relevant info. This is exactly what I needed.

@lgritz lgritz closed this as completed Jan 5, 2020
@lgritz
Copy link
Author

lgritz commented Jan 5, 2020

Follow-up: yep, works great!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants