Сила Pybind11 запечатлена следующей цитатой от Pybind11 Readme:
Pybind11-это легкая библиотека только для заголовков, которая разоблачает типы C ++ в Python и наоборот, в основном для создания привязки Python существующего кода C ++. Его цели и синтаксис похожи на отличную библиотеку Boost.python от Дэвида Абрахамса ...
Основная проблема с Boost.python - и причина создания такого аналогичного проекта - Boost. Boost - это чрезвычайно большой и сложный набор коммунальных библиотек, который работает практически с каждым существующим компилятором C ++. ... Теперь, когда C ++ 11-совместимые компиляторы широко доступны, этот тяжелый механизм стал чрезмерно большой и ненужной зависимостью.
Этот репозиторий содержит несколько примеров для использования Pybind11. Несмотря на то, что онлайн -документация, предоставленная разработчиками Pybind11, делает использование его относительно простым, несколько примеров, таких как предоставленные здесь, делают Pybind11 еще проще в использовании. Эти примеры предназначены для того, чтобы вы начали быстрее с Pybind11. Они, однако, ни в коем случае не исчерпывают и не всегда предоставляют оптимальный выбор. Поэтому очень желательно думать для себя . Кроме того, вклад с аналогичными простыми примерами (или путем дальнейшего улучшения существующих примеров) очень приветствуются . Пожалуйста, подайте запрос на тягу или проблему на GitHub или свяжитесь со мной.
Чтобы отдать должное, если кредит должен:
Создатели Pybind11 проделали отличную работу! Это действительно легко использовать и очень легкий. Также документация уже довольно завершена.
Примеры, предоставленные Клиберн Чан и Дженис Маккарти в Университете Дьюка, оказали огромную помощь. Пожалуйста, также прочитайте их документацию.
Обратите внимание, что существуют также тестовые случаи, которые удваиваются в качестве примеров в репозитории Pybind11, но они не очень проницательны, когда вы новичок в Pybind11.
Наконец, Pybind11 активно используется. Таким образом, можно посмотреть в активно поддерживаемых библиотеках для конкретных решений. Например:
Модуль Pybind11 (только заголовок!) Включен в качестве подмодуля этого репозитория. Это требует некоторого внимания при клонировании этого проекта. Есть два варианта:
Самый простой вариант:
git clone --recursive https://github.com/tdegeus/pybind11_examples.gitЭто загрузит подмодуль до версии, которая используется в этом проекте. Обновить до последней коммиты самого подмодуля:
git submodule update --remoteМожно также напрямую загрузить подмодуль из источника:
git clone https://github.com/tdegeus/pybind11_examples.git
cd pybind11_examples
git submodule init
git submodule updateБиблиотека собственного использования используется в некоторых примерах Numpy. Из этих примеров можно наблюдать, что через Pybind11 Eigen и Numpy действительно являются модулями рукопожатия. Почти код не требуется для создания интерфейса C ++/Python. Обратите внимание, что большая часть простоты зависит от передачи копий, необходимо некоторое внимание, если кто -то хочет пройти исключительно по ссылке.
Собственность не нуждается в установке, потому что он также является только заголовком. Нужно просто загрузить файлы и включить заголовки во время компиляции.
В общем, можно скачать и установить собственное собственное:
mkdir /path/to/temp/build
cmake /path/to/eigen/download
make installДля macOS можно просто использовать
brew install eigen
После этого компилируется с
clang++ -I/path/to/eigen/instalation ...Обратите внимание, что при правильной настройке (что обычно есть), PKG-конфиг может использоваться для отслеживания путей:
clang++ ` pkg-config --cflags eigen3 ` ...Или можно использовать Cmake (см. Ниже).
Если у вас есть простая библиотека, вы можете сделать все самостоятельно. В этом случае вы составляете свой источник C ++ с общим объектом, который связан с Python. Это сводится к
c++ -O3 -shared -std=gnu++11 -I ./pybind11/include ` python3-config --cflags --ldflags --libs ` example.cpp -o example.so -fPIC Приложения Pybind11 могут быть скомпилированы очень легко с помощью Cmake. Для простоты Pybind11 включен в качестве подразделения примеров ниже (фактически используя символическую ссылку на многие копии), чтобы мы могли использовать CMakeLists.txt like:
cmake_minimum_required ( VERSION 2.8.12)
project (example)
add_subdirectory (pybind11)
pybind11_add_module(example example.cpp) (При этом этот пример модуля состоит из одного исходного файла example.cpp ). Чтобы скомпилировать его, используйте:
cd /path/to/build
cmake /path/to/example/src
make Когда собственное «установлено», его можно легко включить, добавив следующее в CMakeLists.txt :
find_package ( PkgConfig )
pkg_check_modules( EIGEN3 REQUIRED eigen3 )
include_directories ( ${EIGEN3_INCLUDE_DIRS} ) Стандарт C ++ 14 может быть использован путем включения следующего в CMakeLists.txt :
set (CMAKE_CXX_STANDARD 14) File setup.py может быть добавлен в вашу библиотеку. Затем вы можете скомпилировать и установить, используя
python3 setup.py build
python3 setup.py install Хотя написание setup.py не сложно, он здесь не покрывается. Можно использовать некоторые инструменты, включенные в CPPMAT, которые могут быть установлены с помощью PIP (например, pip3 install cppmat ). Кроме того, можно посмотреть на setup.py , например, Goosetensor или несколько других моих репозиториев.
В этом примере используется одна modify функция, которая принимает список (только для чтения), умножает все записи на два и возвращает ее в виде списка удвоений (см. example.cpp ). Из Python эта функция содержится в простом example модуля (см. test.py ).
Цель этого примера состоит в том, чтобы показать, как заставить функцию принять список, как преобразовать это в стандартный c ++ std::vector , и как вернуть новый std::vector (или список). Обратите внимание, что фактическая операция не очень важна, это иллюстрируется интерфейс.
Для компиляции, либо используют Cmake, в результате чего инструкции по компиляции читаются из CMakeLists.txt впоследствии:
cmake .
makeИли компилируйте непосредственно с помощью:
c++ -O3 -shared -std=gnu++11 -I ./pybind11/include ` python3-config --cflags --ldflags --libs ` example.cpp -o example.so -fPICЗапустите пример по:
python3 test.pyЧтобы запустить с Python 2, просто замените два случая «Python3» выше «Python». Чтобы изменить инструкции Cmake Найдите больше онлайн.
То же самое, что и предыдущий пример, но с вложенным списком.
modify функция, которая преобразует записи из одномерного массива в целые числа, а затем умножает эти записи на 10.
Цель этого примера состоит в том, чтобы показать, как заставить функцию принять одномерный массив Numpy, как преобразовать это в стандартный C ++ std::vector , и как вернуть одномерный массив Numpy. Обратите внимание, что интерфейс, сгенерированный с использованием Pybind11, настолько гибкий, что он даже принимает входы списков на стороне Python.
Одна length функции. Эта функция принимает «матрицу», в которой содержится список векторов 2-D, в качестве строк. Результатом снова является «матрица» с каждой строкой позиции «x» и «y», а также длина вектора двухмерного положения.
Две функции det и inv , которые используют библиотеку собственных.
Цель этого примера состоит в том, чтобы показать, насколько тривиально взаимодействие между C ++/собственным и Python/Numpy.
Для компиляции с использованием Cmake и для выполнения, следуйте приведенным выше инструкциям (в результате чего заголовки собственных, включенные в CMakeLists.txt . Для непосредственного компиляции, дополнительно должны быть включены заголовки собственных.
c++ -O3 -shared -std=gnu++11 -I /path/to/eigen -I ./pybind11/include ` python3-config --cflags --ldflags --libs ` example.cpp -o example.so -fPICНапример, на MacOs с Homebrew:
c++ -O3 -shared -std=gnu++11 -I /usr/local/Cellar/eigen/3.3.1/include/eigen3 -I ./pybind11/include ` python3-config --cflags --ldflags --libs ` example.cpp -o example.so -fPIC Пользовательский класс CustomVectorXd с одной функцией mul . Этот класс использует библиотеку собственных. Это также включает аргумент по умолчанию.
Кроме того, этот пример имеет функцию trans (совершенно не связан с пользовательским классом CustomVectorXd ). Цель-показать, как вернуть новое Eigen::VectorXi (или numpy-array).
Одна перегруженная функция mul . Эта функция действует «по -разному», если она вызывается с аргументами int или double аргументами. Обратите внимание, что поведение Pybind11 по умолчанию довольно надежно. При вызове функции с одним int и одним double аргументом модуль выберет double версию mul (и выпустит аргумент int в double ).
Для компиляции убедитесь, что стандарт C ++ 14 используется, например, включение -std=c++14 в качестве аргумента компилятора.
Аналогично предыдущему примеру, но с аргументами собственных вещей (т.е. аргументы Numpy со стороны Python).
Для компиляции убедитесь, что используется стандарт C ++ 14.
Этот пример включает в себя пользовательский класс матрицы в C ++ (в matrix.h ). Этот класс связан с Numpy-Array, используя простой интерфейс (в pybind_matrix.h ). Следовательно, функции (в example.cpp ) не требуют какого -либо специального кода обертки.
См. Также это обсуждение переполнения стека.
Этот пример имеет способ взаимодействия с перечислением в C ++. В принципе интерфейс прост, но требует «трюка». Здесь подмодуль используется для взаимодействия с перечислением так же, как в C ++.
Этот пример содержит классический пример, в котором один или несколько классов получены из определенного родителя или шаблона. Этот конкретный пример содержит двух животных, Dog и Cat , которые получены из общего класса Animal . Существует функция talk , которая принимает общее Animal и, следовательно, любой из производных классов.
Этот конкретный случай требует более вовлеченного интерфейса, как описано в документации.
В этом примере есть простой CRTP с AS AS BASION и и класс «полученного» и его регистрацию на API PYBIND11 .
Иногда py::overload_cast не может разрешить вашу функцию, например, когда тип возврата не может быть выведен. В этом случае вы можете быть явным, static_cast обращая внимание на вашу функцию. Дополнительная информация может быть найдена в документации.