差分
このページの2つのバージョン間の差分を表示します。
| 両方とも前のリビジョン前のリビジョン | |||
| youtube:python-mixing-006 [2024/02/28 18:26] – 削除 - 外部編集 (不明な日付) 127.0.0.1 | youtube:python-mixing-006 [2024/02/28 18:26] (現在) – ↷ toybox:python-mixing-006 から youtube:python-mixing-006 へページを移動しました。 freemikan | ||
|---|---|---|---|
| 行 1: | 行 1: | ||
| + | ====== pybind11を使ってみる ====== | ||
| + | |||
| + | 作成日: 2023-08-10 (木) | ||
| + | |||
| + | [[https:// | ||
| + | |||
| + | プロジェクトレイアウト | ||
| + | . | ||
| + | └── pybind11-examples/ | ||
| + | ├── simple/ | ||
| + | │ | ||
| + | │ | ||
| + | └── fakegfx/ | ||
| + | ├── fakegfx.cpp | ||
| + | ├── sample.py | ||
| + | └── Makefile | ||
| + | |||
| + | ===== simple ===== | ||
| + | |||
| + | ==== simple.cpp ==== | ||
| + | |||
| + | <file cpp> | ||
| + | #define _hypot hypot // work-around for Python 3.6 and Mingw-w64 11.0.0 | ||
| + | #include < | ||
| + | namespace py = pybind11; | ||
| + | |||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | namespace s { | ||
| + | |||
| + | struct ZeroDivisionError : std:: | ||
| + | using std:: | ||
| + | }; | ||
| + | |||
| + | void greet(std:: | ||
| + | std::cout << std:: | ||
| + | } | ||
| + | |||
| + | int add(int a, int b) { | ||
| + | return a + b; | ||
| + | } | ||
| + | |||
| + | int sub(int a, int b) { | ||
| + | return a - b; | ||
| + | } | ||
| + | |||
| + | int mul(int a, int b) { | ||
| + | return a * b; | ||
| + | } | ||
| + | |||
| + | int div(int a, int b) { | ||
| + | if (b == 0) { | ||
| + | throw ZeroDivisionError{" | ||
| + | } | ||
| + | return a / b; | ||
| + | } | ||
| + | |||
| + | } // ns s | ||
| + | |||
| + | PYBIND11_MODULE(simple, | ||
| + | m.def(" | ||
| + | m.def(" | ||
| + | m.def(" | ||
| + | m.def(" | ||
| + | m.def(" | ||
| + | py:: | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Makefile ==== | ||
| + | |||
| + | <file Makefile> | ||
| + | MODNAME = simple | ||
| + | |||
| + | PYBIND11_INCLUDES = $(shell pybind11-config --includes) | ||
| + | CXXFLAGS = -Wall -std=c++20 -fPIC ${PYBIND11_INCLUDES} | ||
| + | LDFLAGS = -LC: | ||
| + | LDLIBS = -lpython36 | ||
| + | |||
| + | all: ${MODNAME}.pyd | ||
| + | |||
| + | ${MODNAME}.pyd: | ||
| + | ${CXX} -shared ${CXXFLAGS} -o $@ $< ${LDFLAGS} ${LDLIBS} | ||
| + | | ||
| + | ${MODNAME}.o: | ||
| + | ${CXX} -c ${CXXFLAGS} -o $@ $< | ||
| + | </ | ||
| + | |||
| + | ===== fakegfx ===== | ||
| + | |||
| + | ==== fakegfx.cpp ==== | ||
| + | |||
| + | <file cpp> | ||
| + | #define _hypot hypot // work-around for Python 3.6 and Mingw-w64 11.0.0 | ||
| + | #include < | ||
| + | |||
| + | namespace py = pybind11; | ||
| + | |||
| + | #include < | ||
| + | |||
| + | namespace g { | ||
| + | |||
| + | class Shape { | ||
| + | public: | ||
| + | virtual ~Shape() = default; | ||
| + | virtual void draw() const = 0; | ||
| + | }; | ||
| + | |||
| + | class RectangleShape : public Shape { | ||
| + | public: | ||
| + | void draw() const override { | ||
| + | std::cout << " | ||
| + | << " | ||
| + | << " | ||
| + | << " | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | void draw_shape(Shape const &shape) { | ||
| + | shape.draw(); | ||
| + | } | ||
| + | |||
| + | // trampolines that redirects virtual call back to Python | ||
| + | class PyShape : public Shape { | ||
| + | public: | ||
| + | using Shape:: | ||
| + | |||
| + | void draw() const override { | ||
| + | PYBIND11_OVERRIDE_PURE( | ||
| + | void, // return type | ||
| + | Shape, // parent type | ||
| + | draw, // method name | ||
| + | ); | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | class PyRectangleShape : public RectangleShape { | ||
| + | public: | ||
| + | using RectangleShape:: | ||
| + | void draw() const override { | ||
| + | PYBIND11_OVERRIDE(void, | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | } // namespace g | ||
| + | |||
| + | PYBIND11_MODULE(fakegfx, | ||
| + | py:: | ||
| + | .def(py:: | ||
| + | .def(" | ||
| + | |||
| + | py:: | ||
| + | .def(py:: | ||
| + | .def(" | ||
| + | | ||
| + | m.def(" | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== sample.py ==== | ||
| + | |||
| + | <file python> | ||
| + | import fakegfx | ||
| + | |||
| + | class CircleShape(fakegfx.Shape): | ||
| + | def draw(self): | ||
| + | print(" | ||
| + | |||
| + | class XRectangleShape(fakegfx.RectangleShape): | ||
| + | def draw(self): | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | </ | ||
| + | |||
| + | ==== Makefile ==== | ||
| + | |||
| + | <file Makefile> | ||
| + | MODNAME = fakegfx | ||
| + | |||
| + | PYBIND11_INCLUDES = $(shell pybind11-config --includes) | ||
| + | CXXFLAGS = -Wall -std=c++20 -fPIC ${PYBIND11_INCLUDES} | ||
| + | LDFLAGS = -LC: | ||
| + | LDLIBS = -lpython36 | ||
| + | |||
| + | all: ${MODNAME}.pyd | ||
| + | |||
| + | ${MODNAME}.pyd: | ||
| + | ${CXX} -shared ${CXXFLAGS} -o $@ $< ${LDFLAGS} ${LDLIBS} | ||
| + | | ||
| + | ${MODNAME}.o: | ||
| + | ${CXX} -c ${CXXFLAGS} -o $@ $< | ||
| + | </ | ||
