Ushbu qoʻllanma C++ kutubxonani Python ga oʻrash uchun CMake bilan pybind11 loyihasini qanday oʻrnatishni koʻrsatadi.

Yakuniy natija quyidagicha bo'ladi:

  • pybind11 dan mustaqil ravishda qurishingiz mumkin bo'lgan C++ loyihasi.
  • C++ kodini oʻrash natijasida yaratilgan Python kutubxonasi.
  • Ikkalasi ham CMake dan foydalanadi.

"To'liq loyiha uchun kodni bu erda topishingiz mumkin."

"Rasm manbai."

Talablar

Shubhasiz, pybind11 ni oling:

conda install -c conda-forge pybind11

C++ loyihasini yarating

Python yaratish uchun tashqi (joriy) ishchi katalogdan, C++ kodini yaratish uchun esa cpp nomli ichki katalogdan foydalanamiz. Avval C++ katalogini yarating.

mkdir cpp
cd cpp

Keyinchalik, biz C++ loyihasini ishga tushiramiz. Ikki yo'l (ko'plari) quyidagilar:

  1. VS Code dan foydalanish. CMake Tools kengaytmasini o'rnating. Keyin buyruqlar palitrasini oching va CMake: Quick start ni tanlang. Ko'rsatmalarga rioya qiling va ism kiriting - men automobile ni tanladim. Kutubxona yoki bajariladigan fayl so'ralganda, library ni tanlang. Sizning katalogingiz endi shunday ko'rinishi kerak:
cpp/build/
cpp/motorcycle.cpp
cpp/CMakeLists.txt

Biz manba va sarlavha fayllarini ajratamiz - bu har doim yaxshi amaliyotdir. cpp katalogida ikkita yangi katalog yarating:

cd cpp
mkdir include
mkdir src

va manba faylni ko'chiring:

mv motorcycle.cpp src/

Qo'shish katalogida biz import qilish uchun bitta sarlavhaga ega bo'lishni xohlaymiz. Shunday qilib, biz keyinchalik oddiygina #include <automobile> bo'lishimiz mumkin. Biz uni quyidagicha tashkil qilishimiz mumkin:

cd cpp/include
mkdir automobile_bits
touch automobile

Nihoyat, keling, cpp/include/automobile_bits katalogida sarlavha faylini yarataylik:

cd cpp/include/automobile_bits
touch motorcycle.hpp

Yakuniy katalog tuzilishi endi shunday ko'rinishi kerak:

cpp/build
cpp/CMakeLists.txt
cpp/include/automobile
cpp/include/automobile_bits/motorcycle.hpp
cpp/src/motorcycle.cpp

2. Shu bilan bir qatorda, fayllar va kataloglarni qo'lda yarating, shunday qilib yakuniy tuzilma:

cpp/build
cpp/CMakeLists.txt
cpp/include/automobile
cpp/include/automobile_bits/motorcycle.hpp
cpp/src/motorcycle.cpp

Biz joriy CMakeLists.txt ni sarlavha va manba fayllarni topishi uchun tahrirlashimiz kerak. Men o'zimni quyidagicha o'qish uchun tahrir qildim:

Keling, motorcycle.hpp va motorcycle.cpp fayllariga o'rtacha tarkibni ham beraylik. Sarlavha uchun:

va manba:

Ha! Men ular ahmoq ekanliklarini bilaman. E'tibor bering, biz vehicles nom maydonini taqdim etdik - bu har doim yaxshi fikr.

Shuningdek, biz sarlavha fayli haqiqiy kutubxonani topishimiz kerak. include/automobile faylini oʻqish uchun tahrirlang:

Endi biz kutubxonani qurishimiz mumkin:

  1. Buyruqlar qatoridan foydalanish:
cd cpp/build
cmake ..
make
make install

2. Sevimli IDE dan foydalanish, masalan. XCode:

cd cpp/build
cmake .. -GXcode

build katalogida automobile.xcodeproject hosil qilishi kerak.

Qanday bo'lmasin, kutubxonani qurish va o'rnatish uchun olishingiz kerak.

C++ kutubxonasi sinovdan o'tkazilmoqda

Kutubxonani Python-ga o'rashni davom ettirishdan oldin, keling, C++ kutubxonasi uchun test yarataylik (haqiqiy test emas, shunchaki chalkashishimiz uchun bir joyda!).

cpp da yangi katalog yarating:

cd cpp
mkdir tests

Bu erda biz yana sinovimiz uchun CMake loyihasini o'rnatamiz. Katalog tuzilmasini quyidagicha ko'rinishga keltiring:

cpp/tests/CMakeLists.txt
cpp/tests/src/test.cpp

O'qish uchun test.cpp faylini tahrirlang:

va CMakeLists.txt faylini tahrirlang:

Avvalgidek XCode yoki buyruq satridan foydalanib, bu yomon bolani yarating va boshqaring:

mkdir build
cd build
cmake ..
make
cd ../bin
./test

Ikkilik binkatalogida bo'lishini unutmang. Chiqish quyidagicha bo'lishi kerak:

Made a motorcycle called: Yamaha
Zoom Zoom on road: mullholland

Python oʻramini sozlash

Va nihoyat, keling, kutubxonani Python-ga o'rashga o'taylik. Biz katalogni yuqoriga ko'tarmoqdamiz! Asosiy katalogda python nomli yangi katalog yaratamiz. Unda barcha elim kodlari saqlanadi:

mkdir python

Bizga CMakeLists.txt fayli ham kerak, uning mazmuni:

Siz Python kutubxonangizni yaratishga tayyor bo'lishingiz kerak! Sinab ko'ring:

mkdir build
cd build
cmake .. -DPYTHON_LIBRARY_DIR=”/path/to/site-packages” -DPYTHON_EXECUTABLE=”/path/to/executable/python3"
make
make install

Odatdagidek, siz sevimli IDE uchun generator yordamida kod yaratishingiz mumkin, masalan. cmake buyrug'iga -GXcode qo'shish orqali. Mening yo'llarim:

DPYTHON_LIBRARY_DIR=”/Users/USERNAME/opt/anaconda3/lib/python3.7/site-packages”
DPYTHON_EXECUTABLE=”/Users/USERNAME/opt/anaconda3/bin/python3"

Esda tutingki, agar siz men kabi dangasa bo'lsangiz, testga qo'shishga urinib ko'rishingiz mumkin:

set(PYTHON_LIBRARY_DIR “/Users/USERNAME/opt/anaconda3/lib/python3.7/site-packages”)
set(PYTHON_EXECUTABLE “/Users/USERNAME/opt/anaconda3/bin/python3”)

sizning CMakeLists.txt-da - ishlab chiqarish uchun yaxshi hiyla emasligi aniq!

python ni yoqing (yuqoridagi PYTHON_EXECUTABLE da ko'rsatganingiz bilan bir xil ekanligiga ishonch hosil qiling) va harakat qilib ko'ring:

>>> import automobile
Traceback (most recent call last):
File “<stdin>”, line 1, in <module>
ImportError: dynamic module does not define module export function (PyInit_automobile)

Sizda yaxshi xatolik bor, lekin bu yaxshi! Biz hali elim kodini yozmadik, lekin hech bo'lmaganda CMake ishlayapti va Python kutubxonangizni topa oladi.

Kutubxonani Python-ga o'rash

Endi C++ kodini Python ga o'rashning haqiqiy mantig'i uchun. U python katalogida bo'ladi. Avval python oxirgi qismda shikoyat qilgan "modulni eksport qilish funktsiyasi" ni aniqlaydigan fayl yarating:

touch python/automobile.cpp

Unga quyidagi tarkibni bering:

Keyinchalik, biz e'lon qilingan init_motorcycle usulini aniqlaymiz. Buni alohida faylda qilamiz:

touch python/motorcycle.cpp

O'qish uchun uni tahrirlang:

Men har doim kodning o'zini eng yaxshi tushuntirish deb bilaman, lekin ba'zi ko'rsatkichlar:

  • ”Motorcycle” Python da sinf nomini belgilaydi - agar xohlasangiz, uni o'zgartirishingiz mumkin! Shuningdek, nom maydonining ko'rinishiga e'tibor bering.
  • .def(py::init<std::string>(), py::arg(“name”)) konstruktorni belgilaydi. py::arg(“name”) Python da nomlangan argumentlardan foydalanish imkonini beradi.
  • .def(“get_name”, py::overload_cast<>( &vehicles::Motorcycle::get_name, py::const_)) get_name usulini o'rab oladi. const deklaratsiyasi qanday o'ralganiga e'tibor bering.
  • .def(“ride”, py::overload_cast<std::string>( &vehicles::Motorcycle::ride, py::const_), py::arg(“road”)); ride usulini o'rab oladi. Usulning argumentlari py::overload_cast<std::string> da e'lon qilinadi (agar bir nechta bo'lsa vergul bilan ajratiladi) va ularni yana py::arg(“road”) yordamida nomlash mumkin. Shuningdek, oxirida nuqta-vergulga e'tibor bering - ko'pincha unutiladi, lekin bu to'g'ri C++ kodi bo'lishi kerak.

Endi kutubxonangizni sinab ko'rishingiz mumkin. Kutubxonani qayta tiklash va o'rnatish uchun make va make install ni qayta ishga tushiring.

python ni yoqing va sinab ko'ring:

oldingi kabi bir xil chiqishni berishi kerak:

Made a motorcycle called: Yamaha
Zoom Zoom on road: mullholland

Siz tests/test.py katalogida joylashgan ushbu tarkibga ega boshqa sinov skriptini yaratishingiz mumkin.

Xulosa

Bu ushbu darslik uchun. "To'liq kodni bu erda topishingiz mumkin."

Ushbu sozlashning yoqimli tomoni shundaki, siz o'zingizning C++ loyihangizni cpp katalogidan tinchgina qurishingiz mumkin, so'ngra tashqi qatlam oxirida uni Python ichiga o'rash haqida tashvishlanishingiz mumkin.

Pybind11-ning yanada ilg'or xususiyatlari haqida men bu yerda yozgan boshqa qo'llanmada o'qishingiz mumkin.

O'qiganingiz uchun tashakkur!