I am working on wrapping a C++ class using Pybind11 to make it accessible in Python. My project involves a dynamic library built with Qt6, which contains a class named Package. I am writing a wrapper class called PackageExt, and I am using Pybind11 to bind this wrapper to a Python module. Below is the code I am working with:
C++ Wrapper Header (packageext.h)
#ifndef PACKAGEEXT_H
#define PACKAGEEXT_H
#include "package.h" // from the dynamic library
class PackageExt {
public:
PackageExt(const std::string &id);
PackageExt(const ContainerCore::Package &pkg);
PackageExt(const PackageExt &other);
PackageExt& operator=(const PackageExt &other);
~PackageExt();
void setPackageID(const std::string &id);
std::string packageID() const;
ContainerCore::Package* getBasePackage();
private:
ContainerCore::Package *mPackage; // Defined in the dynamic library
};
#endif // PACKAGEEXT_H
Pybind11 Binding (bindcontainer.cpp)
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "packageext.h"
namespace py = pybind11;
PYBIND11_MODULE(ContainerPy, m) {
m.doc() = "Pybind11 plugin for Container library";
py::class_<PackageExt>(m, "Package")
.def(py::init<const std::string &>(), py::arg("id"),
"Constructor that initializes a Package with the specified ID.")
.def("get_package_id", &PackageExt::packageID,
"Get the package ID as std::string.")
.def("set_package_id", &PackageExt::setPackageID, py::arg("id"),
"Set the package ID using std::string.");
}
CMake Configuration (CMakeLists.txt)
find_package(Python REQUIRED COMPONENTS Interpreter Development)
find_package(QT NAMES Qt6 REQUIRED COMPONENTS Core Concurrent Xml Network Sql)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Concurrent Xml Network Sql)
find_package(pybind11 REQUIRED CONFIG HINTS ${PYBIND11_HINTS_PATH})
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(BINDING_FILES
bindcontainer.cpp
containerext.cpp
packageext.cpp
containermapext.cpp
)
pybind11_add_module(${PYTHON_LIB_NAME} MODULE ${BINDING_FILES})
target_link_libraries(${PYTHON_LIB_NAME} PRIVATE Container) # Dynamic library
target_link_libraries(${PYTHON_LIB_NAME} PRIVATE Qt6::Core Qt6::Concurrent Qt6::Network Qt6::Xml Qt6::Sql)
target_link_libraries(${PYTHON_LIB_NAME} PRIVATE Python::Python)
Issue: After building the module, I successfully get a .pyd file. However, when I import the module in Python and inspect it, I see the following:
python
import ContainerPy
print(dir(ContainerPy))
The output is:
['__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__']
It appears that the Package class and its methods are not being exposed as expected. What could be causing this issue, and how can I troubleshoot or fix it?
Additional Details:
- I am using Qt6 with pybind11 to wrap the C++ class.
- The dynamic library is being linked correctly, and there are no build errors.
- My environment is configured to use CMake for building the project.
- I have verified that the .pyd file is being generated, but the class bindings do not seem to be visible in Python.
- the pyd file ContainerPy/ContainerPy.cpython-313-x86_64-linux-gnu.so is installed in the site-packages folder in my python environment.
- I am building it on linux but the code should be buildable on windows/macos as well.
What I Have Tried:
- I ensured the CMake configuration links to the required Qt6 and Python components.
- I verified that all source files are included in the BINDING_FILES list.
- I checked for any missing dependencies that could cause the class bindings not to appear.
Questions:
- Could there be an issue with how I set up the Pybind11 bindings?
- Is there anything specific I should check in the CMake configuration or the way the library is being linked?
python, is the .pyd in the current directory? If you print something inside ofPYBIND11_MODULE, does it get printed when you import the module?PYTHONVERBOSE=2, it should tell you what it imports..pyddirectly tosite-packages/and get rid ofContainerPy/directory. I think Python can treat directories as modules, so the full name of your module isContainerPy.ContainerPy, or something.