[QUESTION] Working with a C++ library that has boost::python bindings
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 18k
- Forks
- 2.3k
- Avg merge
- 5d 17h
- Merged PRs (30d)
- 10
Description
Problem Descriptiopn
Hello there, I'm actually using a 3dparty library that provides python bindings... but sadly they didn't use pybind11 😢 ...
I need to interact with the python objects created by the library(from Python) with a C++ API. So far I made it work but I don't like at all how it's looking:
- It's too hacky
- It doesn't support type checking, my wrapper accepts a
PyObject*, basically anything created from a python session - I did some "manual" type checking, but, again, it's ugly
- It adds
boost::pytonas an extra dependency
Solution provided so far
template <typename ClassType>
typename ClassType::Ptr convert_to_class_type(py::object py_obj) {
boost::python::extract<typename ClassType::Ptr> x(py_obj.ptr());
if (x.check()) {
return x();
} else {
throw std::invalid_argument("ClassType not supported");
}
}
template <typename ClassType>
void Wrapper(py::object py_obj) {
auto obj = convert_to_class_type<ClassType>(py_obj);
// do some stuff with the obj..
}
PYBIND11_MODULE(dummy_module, m) {
m.def("ClassTypeWrapper", &Wrapper<CustomLibraryType>);
}
What I would like to write:
template <typename ClassType>
void Wrapper(ClassType obj) {
// do some stuff with the obj... no conversion needed
}
PYBIND11_MODULE(dummy_module, m) {
m.def("ClassTypeWrapper", &Wrapper<CustomLibraryType>);
}
An extra example
So, I use a lot of the Open3D library. And whenever I write C++ code it just works out of the box with Open3D types:
#include <open3d/geometry/PointCloud.h>
#include <pybind11/pybind11.h>
namespace py = pybind11;
void Process(const o3d::geometry::PointCloud& point_cloud) {}
PYBIND11_MODULE(cloud_module, m) { m.def("process", &Process); }
Whenever I build that small module I can run the following code
import cloud_module
import open3d as o3d
pcd = o3d.geometry.PointCloud()
cloud_module.process(pcd)
If I don't use the right o3d.geometry.PointCloud() type, then there will be a runtime error
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-2-4f2097197c74> in <module>
3
4 mesh = o3d.geometry.TriangleMesh()
----> 5 cloud_module.process(mesh)
TypeError: process(): incompatible function arguments. The following argument types are supported:
1. (arg0: open3d::geometry::PointCloud) -> None
Invoked with: TriangleMesh with 0 points and 0 triangles.
Which is the expected behavior.
Final Question
I've checked the Custom type caters but doesn't seem to be the right solution.
Is there any easy way to achieve this?
Thanks in advance!!!
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the custom type casters documentation and the PYBIND11_MODULE/Wrapper entry points shown in the issue; compare them with the typed binding behavior demonstrated by Open3D. Determine whether pybind11 supports this third-party boost::python-bound object use case without the extra dependency, and document the supported outcome.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, python
- Domain
- api
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100