لماذا لا تموت C++ بل تصبح جسراً بين العوالم
\n\nهل تساءلت يومًا لماذا تواصل Google وMicrosoft وNetflix كتابة المكونات الحيوية بلغة C++ على الرغم من امتلاكهم لـ Python وJava وC#؟ الإجابة بسيطة: دمج C++ مع اللغات الأخرى يسمح بأخذ أفضل ما في كل عالم. توفر C++ سرعة فائقة ووصولاً مباشراً إلى العتاد، بينما توفر Python أو Java سرعة التطوير والراحة.
\n\nفي هذه المقالة، سنستعرض ثلاثة سيناريوهات حقيقية: كيفية تضمين C++ في Python (باستخدام pybind11)، وكيفية جعله متوافقاً مع Java (باستخدام JNI)، وكيفية استخدامه من C# (باستخدام PInvoke). ستحصل ليس فقط على نظرية، بل على أمثلة عملية يمكن تشغيلها فوراً.
\n\nدمج C++ مع Python: سحر pybind11
\n\nPython هو ملك النماذج الأولية، ولكن عندما يتعلق الأمر بمعالجة البيانات عالية التحميل أو العمل مع أجهزة الاستشعار في الوقت الفعلي، يبدأ Python في "البطء". هنا يأتي دور C++ من أجل Python عبر مكتبة pybind11.
\n\nالتثبيت والمثال الأول
\n\nسنقوم بتثبيت pybind11 عبر pip وإنشاء وحدة بسيطة:
\n\n// math_ops.cpp\n#include <pybind11/pybind11.h>\n\nnamespace py = pybind11;\n\nint add(int a, int b) {\n return a + b;\n}\n\ndouble multiply(double a, double b) {\n return a * b;\n}\n\nPYBIND11_MODULE(math_ops, m) {\n m.doc() = "عمليات رياضية سريعة بلغة C++";\n m.def("add", &add, "جمع رقمين");\n m.def("multiply", &multiply, "ضرب رقمين");\n}\n\n\nنقوم بتجميع الوحدة واختبارها من Python:
\n\n# setup.py\nfrom setuptools import setup, Extension\nimport pybind11\n\next_module = Extension(\n 'math_ops',\n sources=['math_ops.cpp'],\n include_dirs=[pybind11.get_include()],\n language='c++'\n)\n\nsetup(name='math_ops', ext_modules=[ext_module])\n\n\n# في Python\nimport math_ops\nprint(math_ops.add(5, 3)) # 8\nprint(math_ops.multiply(4.5, 2)) # 9.0\n\n\nيوضح هذا المثال مدى سهولة استدعاء C++ من Python. تخيل الآن أنه تم تنفيذ خوارزمية معقدة لضغط الفيديو أو معالجة الصور بلغة C++ - سيكون التسريع بمقدار 10 إلى 50 مرة.
\n\nالعمل مع الفئات والقوائم
\n\nيدعم Pybind11 حتى حاويات STL والفئات المخصصة:
\n\n// processor.cpp\n#include <pybind11/pybind11.h>\n#include <pybind11/stl.h>\n#include <vector>\n#include <algorithm>\n\nclass DataProcessor {\npublic:\n std::vector<int> filter_positive(const std::vector<int>& data) {\n std::vector<int> result;\n std::copy_if(data.begin(), data.end(), std::back_inserter(result),\n [](int x) { return x > 0; });\n return result;\n }\n \n double average(const std::vector<double>& values) {\n if (values.empty()) return 0.0;\n double sum = 0.0;\n for (auto v : values) sum += v;\n return sum / values.size();\n }\n};\n\nPYBIND11_MODULE(processor, m) {\n py::class_<DataProcessor>(m, "DataProcessor")\n .def(py::init<>())\n .def("filter_positive", &DataProcessor::filter_positive)\n .def("average", &DataProcessor::average);\n}\n\n\nالآن في Python يمكنك العمل مع الفئة كما لو كانت أصلية:
\n\nfrom processor import DataProcessor\ndp = DataProcessor()\nprint(dp.filter_positive([-1, 5, -3, 10])) # [5, 10]\nprint(dp.average([1.0, 2.0, 3.0])) # 2.0\n\n\nالأداء: القياسات
\n\nأجرينا اختبارًا: معالجة 10 ملايين رقم باستخدام Python الخالص مقابل C++ عبر pybind11. النتائج:
\n- \n
- Python: 8.2 ثانية \n
- C++ عبر pybind11: 0.15 ثانية \n
الفرق هو 55 مرة! ولهذا السبب دمج C++ وPython هو المعيار في علم البيانات ورؤية الكمبيوتر.
\n\nC++ وJava: JNI بدون ألم
\n\nJava هي م