Python package using Pybind11
설치
sudo apt install -y libffi-dev python3 python3-pip python3-dev \
&& python3 -m pip install -U pip setuptools wheel twine keyrings.alt pybind11 build
Package directory structure
workspace
├── LICENSE
├── MANIFEST.in
├── README.md
├── CHANGELOG
├── setup.cfg
├── setup.py
├── c_src
│ └── ...
└── py_src
└── package
├── test
| ├── __init__.py
| └── ...
├── subPackage
│ ├── __init__.py
│ └── module1.py
├── __init__.py
└── __main__.py
C/C++
function
#include <pybind11/pybind11.h>
namespace py = pybind11;
int add(int i, int j) { return i + j; }
PYBIND11_MODULE(_<package>, m) {
// m.def( "add", &add );
m.def("add",
&add,
"A function which adds two numbers",
py::arg("i") = 1,
py::arg("j") = 2);
}
variable
#include <pybind11/pybind11.h>
namespace py = pybind11;
PYBIND11_MODULE(_<package>, m) {
// Built-in types and general objects (more on that later)
// are automatically converted.
m.attr("var1") = 10;
// Can be explicitly converted using the function `py::cast`.
py::object var2 = py::cast("It is string");
m.attr("var2") = var2;
}
class
#include <pybind11/pybind11.h>
#include <string>
namespace py = pybind11;
class TestClass {
public:
TestClass(int a);
~TestClass();
int add(int a, int b);
int sub(int a, int b);
float sub(float a, float b);
std::string get_name(void);
void set_name(std::string name);
private:
std::string name;
};
PYBIND11_MODULE(_<package>, m) {
py::class_<TestClass>(m, "TestClass")
.def(py::init<int>())
.def("add", &TestClass::add)
.def("sub", (int (TestClass::*)(int, int)) & TestClass::sub)
.def("sub", (float (TestClass::*)(float, float)) & TestClass::sub)
// .def_readwrite( "name", &TestClass::name ) // public
.def_property(
"name", &TestClass::get_name, &TestClass::set_name); // private
}
Python
__init__.py
from <package>._<package> import *
...
Build
pyproject.toml
[build-system]
requires = [
"setuptools>=42",
"wheel",
"pybind11>=2.6.0",
]
build-backend = "setuptools.build_meta"