دليل pybind11 الشامل لربط C++ مع Python

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

pybind11: إنشاء روابط Python لكود C++

pybind11 هي مكتبة خفيفة الوزن، تعتمد على ملفات الرأس (header-only) للغة C++، تتيح لك إنشاء روابط (bindings) عالية الأداء بين كود C++ و Python. تُعتبر بديلاً حديثًا وأسهل من مكتبة Boost.Python. الفكرة الأساسية هي أن تكتب طبقة "لاصقة" صغيرة بلغة C++ باستخدام ماكروات وقوالب pybind11، ثم يتم تجميعها في مكتبة ديناميكية (ملف .so أو .pyd). بعد ذلك، يمكن استيراد هذا الملف في Python كوحدة نمطية عادية.

لماذا تحتاج هذا؟ في المشاريع الواقعية، غالبًا ما تحتاج للجمع بين الأداء العالي والتحكم منخفض المستوى الذي توفره C++، وبين مرونة Python ونظامها البيئي الغني. يمكنك كتابة الكود الحرج من حيث السرعة (خوارزميات رقمية، معالجة صور، التعامل مع الأجهزة) بلغة C++، ثم استخدامه من Python مع الحفاظ على سهولة النمذجة الأولية وتحليل البيانات. pybind11 تجعل هذه العملية بسيطة وبديهية، حيث تتعامل تلقائيًا مع تحويل الأنواع، وإدارة الذاكرة، ومعالجة الاستثناءات.

المزايا الرئيسية لـ pybind11: تكلفة إضافية ضئيلة (overhead) عند استدعاء الدوال، دعم كامل للغة C++ الحديثة (C++11 وما فوق)، تحويل تلقائي للحاويات القياسية (std::vector, std::map) إلى قوائم وقواميس Python، بالإضافة إلى نظام بسيط ومعبر لتسجيل الكلاسات والدوال والخصائص. المكتبة في تطور نشط وتُستخدم في مشاريع كبرى مثل PyTorch و TensorFlow و Open3D.

التثبيت

pybind11 هي مكتبة تعتمد على ملفات الرأس، لذا فإن تثبيتها يتلخص في نسخ ملفات الرأس إلى مشروعك. الطريقة الأسهل والموصى بها هي استخدام مدير الحزم pip، الذي سيقوم بتثبيت المكتبة في النظام وتوفير أداة pybind11-config للحصول على مسارات الترجمة:

pip install pybind11

بعد التثبيت، يمكنك التحقق من أن كل شيء يعمل عن طريق تنفيذ الأمر:

pybind11-config --includes

سيقوم هذا الأمر بعرض علامات المترجم اللازمة لتضمين ملفات رأس pybind11. لتجميع الوحدة، ستحتاج أيضًا إلى مترجم C++ (g++, clang, MSVC) وملفات رأس Python (التي تُثبت عادةً مع Python). مثال على التجميع باستخدام CMake أو مباشرة عبر g++:

c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) example.cpp -o example$(python3-config --extension-suffix)

بداية سريعة: مثال عملي مصغر

أنشئ ملفًا باسم example.cpp بالمحتوى التالي:

#include <pybind11/pybind11.h>

namespace py = pybind11;

int add(int i, int j) {
    return i + j;
}

PYBIND11_MODULE(example, m) {
    m.doc() = "مثال على إضافة pybind11";
    m.def("add", &add, "دالة لجمع رقمين");
}

قم بتجميعه (استبدل python3 بمفسر Python الخاص بك):

c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) example.cpp -o example$(python3-config --extension-suffix)

الآن يمكنك استخدام الوحدة من Python:

import example
result = example.add(3, 4)
print(result)  # سيطبع: 7
print(example.__doc__)  # سيطبع: مثال على إضافة pybind11

الدوال والكلاسات الأساسية في pybind11

فيما يلي الدوال والكلاسات الرئيسية في المكتبة المستخدمة لإنشاء الروابط.

1. PYBIND11_MODULE(name, variable)

التوقيع: PYBIND11_MODULE(name, variable) (ماكرو)

الوظيفة: يحدد نقطة الدخول لوحدة Python. ينشئ دالة تهيئة يتم استدعاؤها تلقائيًا عند استيراد الوحدة. name هو اسم الوحدة (بدون علامات اقتباس)، و variable (من النوع py::module_&) هو المتغير الذي ستسجل فيه الدوال والكلاسات.

توصيات