ユーザ用ツール

サイト用ツール


youtube:python-mixing-006

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
youtube:python-mixing-006 [2024/02/28 18:26] – 削除 - 外部編集 (不明な日付) 127.0.0.1youtube:python-mixing-006 [2024/02/28 18:26] (現在) – ↷ toybox:python-mixing-006 から youtube:python-mixing-006 へページを移動しました。 freemikan
行 1: 行 1:
 +====== pybind11を使ってみる ======
 +
 +作成日: 2023-08-10 (木)
 +
 +[[https://youtu.be/PXEZhuwq0xA|第6回 pybind11を使ってみる]]
 +
 +プロジェクトレイアウト
 +  .
 +  └── pybind11-examples/
 +      ├── simple/
 +      │   ├── simple.cpp
 +      │   └── Makefile
 +      └── 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 <pybind11/pybind11.h>
 +namespace py = pybind11;
 +
 +#include <string_view>
 +#include <format>
 +#include <iostream>
 +
 +namespace s {
 +
 +struct ZeroDivisionError : std::runtime_error {
 +    using std::runtime_error::runtime_error;
 +};
 +
 +void greet(std::string_view who) {
 +    std::cout << std::format("Hello, {}!\n", who);
 +}
 +
 +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{"division by zero"};
 +    }
 +    return a / b;
 +}
 +
 +} // ns s
 +
 +PYBIND11_MODULE(simple, m) {
 +    m.def("greet", &s::greet, "Greet to user with Hello.");
 +    m.def("add", &s::add, "Add first and second numbers.");
 +    m.def("sub", &s::sub, "Subtract second number from first one.");
 +    m.def("mul", &s::mul, "Multiply first and second numbers.");
 +    m.def("div", &s::div, "Divide first number by second one.");
 +    py::register_exception<s::ZeroDivisionError>(m, "ZeroDivisionError", PyExc_ZeroDivisionError);
 +}
 +</file>
 +
 +==== Makefile ====
 +
 +<file Makefile>
 +MODNAME = simple
 +
 +PYBIND11_INCLUDES = $(shell pybind11-config --includes)
 +CXXFLAGS = -Wall -std=c++20 -fPIC ${PYBIND11_INCLUDES}
 +LDFLAGS = -LC:\Python36\libs
 +LDLIBS = -lpython36
 +
 +all: ${MODNAME}.pyd
 +
 +${MODNAME}.pyd: ${MODNAME}.o
 + ${CXX} -shared ${CXXFLAGS} -o $@ $< ${LDFLAGS} ${LDLIBS} 
 +    
 +${MODNAME}.o: ${MODNAME}.cpp
 + ${CXX} -c ${CXXFLAGS} -o $@ $<
 +</file>
 +
 +===== fakegfx =====
 +
 +==== fakegfx.cpp ====
 +
 +<file cpp>
 +#define _hypot hypot  // work-around for Python 3.6 and Mingw-w64 11.0.0
 +#include <pybind11/pybind11.h>
 +
 +namespace py = pybind11;
 +
 +#include <iostream>
 +
 +namespace g {
 +
 +class Shape {
 +public:
 +    virtual ~Shape() = default;
 +    virtual void draw() const = 0;
 +};
 +
 +class RectangleShape : public Shape {
 +public:
 +    void draw() const override {
 +        std::cout << "+---------+\n"
 +                  << "        |\n"
 +                  << "        |\n"
 +                  << "+---------+\n";
 +    }
 +};
 +
 +void draw_shape(Shape const &shape) {
 +    shape.draw();
 +}
 +
 +// trampolines that redirects virtual call back to Python
 +class PyShape : public Shape {
 +public:
 +    using Shape::Shape;
 +
 +    void draw() const override {
 +        PYBIND11_OVERRIDE_PURE(
 +            void,  // return type
 +            Shape, // parent type
 +            draw,  // method name
 +        );
 +    }
 +};
 +
 +class PyRectangleShape : public RectangleShape {
 +public:
 +    using RectangleShape::RectangleShape;
 +    void draw() const override {
 +        PYBIND11_OVERRIDE(void, RectangleShape, draw);
 +    }
 +};
 +
 +} // namespace g
 +
 +PYBIND11_MODULE(fakegfx, m) {
 +    py::class_<g::Shape, g::PyShape>(m, "Shape")
 +        .def(py::init())
 +        .def("draw", &g::Shape::draw);
 +
 +    py::class_<g::RectangleShape, g::Shape, g::PyRectangleShape>(m, "RectangleShape")
 +        .def(py::init())
 +        .def("draw", &g::RectangleShape::draw);
 +        
 +    m.def("draw_shape", &g::draw_shape);
 +}
 +</file>
 +
 +==== sample.py ====
 +
 +<file python>
 +import fakegfx
 +
 +class CircleShape(fakegfx.Shape):
 +    def draw(self):
 +        print("o")
 +
 +class XRectangleShape(fakegfx.RectangleShape):
 +    def draw(self):
 +        print("x x x x x x")
 +        print("        x")
 +        print("        x")
 +        print("x x x x x x")
 +</file>
 +
 +==== Makefile ====
 +
 +<file Makefile>
 +MODNAME = fakegfx
 +
 +PYBIND11_INCLUDES = $(shell pybind11-config --includes)
 +CXXFLAGS = -Wall -std=c++20 -fPIC ${PYBIND11_INCLUDES}
 +LDFLAGS = -LC:\Python36\libs
 +LDLIBS = -lpython36
 +
 +all: ${MODNAME}.pyd
 +
 +${MODNAME}.pyd: ${MODNAME}.o
 + ${CXX} -shared ${CXXFLAGS} -o $@ $< ${LDFLAGS} ${LDLIBS} 
 +    
 +${MODNAME}.o: ${MODNAME}.cpp
 + ${CXX} -c ${CXXFLAGS} -o $@ $<
 +</file>
  

特に明示されていない限り、本Wikiの内容は次のライセンスに従います: CC0 1.0 Universal
CC0 1.0 Universal Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki