พลังของ pybind11 ถูกจับโดยการอ้างอิงต่อไปนี้จาก readme ของ Pybind11:
PyBind11 เป็นไลบรารีส่วนหัวที่มีน้ำหนักเบาเท่านั้นที่แสดงให้เห็นถึงประเภท C ++ ใน Python และในทางกลับกันโดยส่วนใหญ่จะสร้างการผูก python ของรหัส C ++ ที่มีอยู่ เป้าหมายและไวยากรณ์นั้นคล้ายกับห้องสมุด Boost.python ที่ยอดเยี่ยมโดย David Abrahams ...
ปัญหาหลักของ boost.python - และเหตุผลในการสร้างโครงการที่คล้ายกัน - คือการเพิ่ม Boost เป็นห้องสมุดยูทิลิตี้ที่มีขนาดใหญ่และซับซ้อนซึ่งทำงานร่วมกับคอมไพเลอร์ C ++ เกือบทุกตัวที่มีอยู่ ... ตอนนี้คอมไพเลอร์ที่เข้ากันได้กับ C ++ 11 มีให้บริการอย่างกว้างขวางเครื่องจักรหนักนี้ได้กลายเป็นการพึ่งพาที่มีขนาดใหญ่และไม่จำเป็นมากเกินไป
ที่เก็บนี้มีหลายตัวอย่างสำหรับการใช้งานของ Pybind11 แม้ว่าเอกสารออนไลน์ที่จัดทำโดยนักพัฒนาของ Pybind11 จะทำให้การใช้งานค่อนข้างตรงไปตรงมา แต่มีหลายตัวอย่าง - เช่นที่ระบุไว้ที่นี่ - ทำให้ Pybind11 ใช้งานง่ายขึ้น ตัวอย่างเหล่านี้มีความหมายสำหรับคุณที่จะเริ่มต้นเร็วขึ้นด้วย pybind11 อย่างไรก็ตามพวกเขาไม่ได้ครบถ้วนสมบูรณ์และไม่ได้เป็นตัวเลือกที่ดีที่สุดเสมอไป ดังนั้นจึงขอแนะนำให้ คิดด้วยตัวเอง อย่างมาก นอกจากนี้ การมีส่วนร่วมที่มีตัวอย่างง่าย ๆ ที่คล้ายกัน (หรือโดยการปรับปรุงตัวอย่างที่มีอยู่เพิ่มเติม) ยินดีต้อนรับอย่างมาก โปรดยื่นคำขอดึงหรือปัญหาเกี่ยวกับ GitHub หรือติดต่อฉัน
เพื่อให้เครดิตในกรณีที่เครดิตถึงกำหนด:
ผู้สร้าง Pybind11 ได้ผลดีมาก! มันใช้งานง่ายและมีน้ำหนักเบามาก นอกจากนี้เอกสารยังค่อนข้างสมบูรณ์
ตัวอย่างที่จัดทำโดย Cliburn Chan และ Janice McCarthy ที่ Duke University ได้รับความช่วยเหลืออย่างมาก โปรดอ่านเอกสารของพวกเขาด้วย
โปรดทราบว่านอกจากนี้ยังมีกรณีทดสอบที่สองเท่าเป็นตัวอย่างในที่เก็บ pybind11 แต่สิ่งเหล่านี้ไม่ได้ลึกซึ้งมากเมื่อคุณยังใหม่กับ Pybind11
ในที่สุด Pybind11 ก็ถูกใช้อย่างแข็งขัน ดังนั้นเราสามารถดูในห้องสมุดที่ได้รับการดูแลรักษาอย่างแข็งขันสำหรับโซลูชันเฉพาะ ตัวอย่างเช่น:
โมดูล PYBIND11 (ซึ่งเป็นส่วนหัวเท่านั้น!) รวมอยู่ในรูปแบบของที่เก็บนี้ สิ่งนี้ต้องการความสนใจเมื่อโคลนโครงการนี้ มีสองตัวเลือก:
ตัวเลือกที่ง่ายที่สุดคือ:
git clone --recursive https://github.com/tdegeus/pybind11_examples.gitสิ่งนี้จะดาวน์โหลด submodule ไปยังเวอร์ชันที่ใช้ในโครงการนี้ หากต้องการอัปเดตการกระทำล่าสุดของ submodule เอง:
git submodule update --remoteหนึ่งสามารถดาวน์โหลด submodule โดยตรงจากแหล่งที่มา:
git clone https://github.com/tdegeus/pybind11_examples.git
cd pybind11_examples
git submodule init
git submodule updateไลบรารี Eigen ใช้ในตัวอย่าง Numpy บางส่วน จากตัวอย่างเหล่านี้สามารถสังเกตได้ว่าผ่าน pybind11, eigen และ numpy เป็นโมดูลจับมือกันจริงๆ แทบไม่จำเป็นต้องใช้รหัสเพื่อสร้างอินเตอร์เฟส C ++/Python โปรดทราบว่าความเรียบง่ายส่วนใหญ่ขึ้นอยู่กับสำเนาที่ผ่านมาจำเป็นต้องให้ความสนใจบางอย่างหากต้องการผ่านการอ้างอิงอย่างหมดจด
Eigen ไม่จำเป็นต้องมีการติดตั้งเพราะมันเป็นส่วนหัวเท่านั้น เพียงแค่ต้องดาวน์โหลดไฟล์และรวมส่วนหัวในเวลาคอมไพล์
โดยทั่วไปสามารถดาวน์โหลดและติดตั้ง eigen ได้โดย:
mkdir /path/to/temp/build
cmake /path/to/eigen/download
make installสำหรับ macOS หนึ่งสามารถใช้ได้ง่ายๆ
brew install eigen
หลังจากนั้นคอมไพล์ด้วย
clang++ -I/path/to/eigen/instalation ...โปรดทราบว่าเมื่อกำหนดค่าอย่างถูกต้อง (ซึ่งเป็นกรณี) PKG-Config สามารถใช้เพื่อติดตามเส้นทาง:
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 ได้เช่น:
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 เมื่อ eigen ถูก 'ติดตั้ง' สามารถรวมได้อย่างง่ายดายโดยการเพิ่มสิ่งต่อไปนี้ใน 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) สามารถเพิ่มไฟล์ 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 มิติเป็นแถว ผลที่ได้คือ 'เมทริกซ์' อีกครั้งสำหรับแต่ละแถว "X" และ "y" ตำแหน่งและความยาวของเวกเตอร์ตำแหน่ง 2 มิติ
สองฟังก์ชั่น det และ inv ที่ใช้ไลบรารี eigen
วัตถุประสงค์ของตัวอย่างนี้คือการแสดงให้เห็นว่าการโต้ตอบระหว่าง C ++/eigen และ python/numpy เป็นเพียงเล็กน้อย
ในการรวบรวมโดยใช้ cmake และการรันให้ทำตามคำแนะนำด้านบน (โดยที่ส่วนหัว eigen จะรวมอยู่ใน CMakeLists.txt . เพื่อรวบรวมโดยตรงนอกจากนี้ยังต้องรวมส่วนหัว eigen เพิ่มเติม:
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 คลาส Custom CustomVectorXd พร้อมฟังก์ชั่นเดียว mul คลาสนี้ใช้ไลบรารี Eigen นอกจากนี้ยังมีอาร์กิวเมนต์เริ่มต้น
นอกจากนี้ตัวอย่างนี้มีฟังก์ trans (ไม่เกี่ยวข้องกับคลาส CustomVectorXd ที่กำหนดเองทั้งหมด) มันมีจุดประสงค์คือการแสดงวิธีการส่งคืน Eigen::VectorXi (หรือ numpy-array)
หนึ่งฟังก์ชั่นโอเวอร์โหลด mul ฟังก์ชั่นนี้ทำหน้าที่ 'แตกต่างกัน' หากเรียกด้วยอาร์กิวเมนต์ int หรืออาร์กิวเมนต์ double ขอให้สังเกตว่าพฤติกรรมเริ่มต้นของ PyBind11 นั้นค่อนข้างแข็งแกร่ง เมื่อเรียกฟังก์ชั่นที่มีหนึ่ง int และหนึ่งอาร์กิวเมนต์ double โมดูลจะเลือก mul เวอร์ชัน double (และจะทำให้อาร์กิวเมนต์ int เป็น double )
ในการรวบรวมตรวจสอบให้แน่ใจว่ามีการใช้มาตรฐาน C ++ 14 ตัวอย่างเช่นการรวม -std=c++14 เป็นอาร์กิวเมนต์คอมไพเลอร์
คล้ายกับตัวอย่างก่อนหน้า แต่มีอาร์กิวเมนต์ eigen (เช่นอาร์กิวเมนต์ numpy จากด้าน Python)
ในการรวบรวมตรวจสอบให้แน่ใจว่าใช้มาตรฐาน C ++ 14
ตัวอย่างนี้รวมคลาสเมทริกซ์ที่กำหนดเองใน C ++ (ใน matrix.h ) คลาสนี้เชื่อมต่อกับ numpy-array โดยใช้อินเทอร์เฟซอย่างง่าย (ใน pybind_matrix.h ) ดังนั้นฟังก์ชั่น (ใน example.cpp ) ไม่จำเป็นต้องใช้รหัสห่อพิเศษใด ๆ
ดูการสนทนาของสแต็คล้น
ตัวอย่างนี้มีวิธีการเชื่อมต่อกับ enumerator ใน C ++ โดยหลักการแล้วอินเทอร์เฟซนั้นตรงไปตรงมา แต่รับประกันว่า 'เคล็ดลับ' ที่นี่มีการใช้ submodule เพื่อให้สามารถโต้ตอบกับ enumerator ในลักษณะเดียวกับใน C ++
ตัวอย่างนี้มีตัวอย่างคลาสสิกที่หนึ่งคลาสหรือมากกว่านั้นมาจากพาเรนต์หรือแม่แบบที่แน่นอน ตัวอย่างนี้มีสัตว์สอง Dog และ Cat ที่ได้มาจากชั้น Animal ทั่วไป มีฟังก์ชั่น talk ที่ยอมรับ Animal ทั่วไปและทำให้ชั้นเรียนใด ๆ ที่ได้รับ
กรณีเฉพาะนี้ต้องการอินเทอร์เฟซที่เกี่ยวข้องมากขึ้นตามที่อธิบายไว้ในเอกสาร
ตัวอย่างนี้มี CRTP อย่างง่ายด้วยคลาส 'ฐาน' และและคลาส 'ที่ได้รับ' และการลงทะเบียนไปยัง PYBIND11 API
บางครั้ง py::overload_cast ไม่สามารถแก้ไขฟังก์ชั่นของคุณได้เช่นเมื่อประเภทการส่งคืนไม่สามารถอนุมานได้ ในกรณีนี้คุณสามารถชัดเจนโดย static_cast ing ตัวชี้ไปยังฟังก์ชั่นของคุณข้อมูลเพิ่มเติมสามารถพบได้ในเอกสารประกอบ