العمل مع WebAssembly وC++: من الألف إلى الياء

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

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

ابدأ الدورة

مقدمة في WebAssembly وC++

\n\n

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

\n\n

في هذه المقالة، سننتقل من الأساسيات إلى التطبيق العملي: سنشرح كيفية ترجمة كود C++ إلى WebAssembly، وتشغيله في المتصفح، وتحسينه لتحقيق أقصى أداء.

\n\n

1. الأدوات وإعداد البيئة

\n\n

الأداة الرئيسية لترجمة C++ إلى WebAssembly هي مجموعة المترجمات Emscripten. يقوم بتحويل LLVM bytecode إلى Wasm ويقوم تلقائيًا بإنشاء كود JavaScript اللازم (glue code) لتحميل الوحدة.

\n\n

تثبيت Emscripten

\n

الطريقة الموصى بها للتثبيت هي من خلال مدير الحزم emsdk:

\n\n
# استنساخ المستودع\ngit clone https://github.com/emscripten-core/emsdk.git\ncd emsdk\n\n# تثبيت وتفعيل أحدث إصدار\n./emsdk install latest\n./emsdk activate latest\n\n# إضافة متغيرات البيئة (متغيرات الصدفة)\nsource ./emsdk_env.sh
\n\n

بعد التثبيت، سيكون لديك الأوامر emcc (مترجم) و em++ (مترجم C++)، وهما غلافان حول Clang.

\n\n

2. ترجمة C++ إلى WebAssembly

\n\n

لنأخذ مثالًا بسيطًا. لننشئ ملفًا باسم hello.cpp:

\n\n
#include <emscripten/emscripten.h>\n\n// دالة متاحة من JavaScript\nextern "C" {\n    int EMSCRIPTEN_KEEPALIVE add(int a, int b) {\n        return a + b;\n    }\n}
\n\n

العنصر المهم هو الماكرو EMSCRIPTEN_KEEPALIVE. يمنع إزالة الدالة بواسطة المحسن ويجعلها قابلة للتصدير.

\n\n

لنقم بترجمة الكود الخاص بنا:

\n\n
em++ hello.cpp -o hello.html -s WASM=1 -s EXPORTED_FUNCTIONS='["_add"]' -O3
\n\n

دعنا نشرح العلامات:

\n
    \n
  • -o hello.html — ينشئ ملف HTML مع مثال للتشغيل.
  • \n
  • -s WASM=1 — يحدد بوضوح توليد Wasm (مفعل افتراضيًا).
  • \n
  • -s EXPORTED_FUNCTIONS='["_add"]' — قائمة الدوال المصدرة (مع البادئة _).
  • \n
  • -O3 — مستوى عالٍ من التحسين.
  • \n
\n\n

النتيجة هي ثلاثة ملفات: hello.html و hello.js (glue code) و hello.wasm.

\n\n

3. التفاعل مع JavaScript

\n\n

بعد الترجمة، يمكننا استدعاء دالة C++ الخاصة بنا من JavaScript. إليك كود تحميل الوحدة الأدنى:

\n\n
<!DOCTYPE html>\n<html>\n<head>\n    <script>\n        var Module = {};\n        Module.onRuntimeInitialized = function() {\n            // الدالة add متاحة الآن\n            var result = Module._add(5, 7);\n            console.log("النتيجة: " + result); // 12\n        };\n    </script>\n    <script src="hello.js"></script>\n</head>\n<body></body>\n</html>
\n\n

النقاط الرئيسية:

\n
    \n
  • Module.onRuntimeInitialized — حدث يتم استدعاؤه بعد تحميل وحدة Wasm.
  • \n
  • أسماء الدوال في JavaScript تحصل على البادئة _ (مثل _add).
  • \n
  • لنقل هياكل البيانات المعقدة (سلاسل، مصفوفات) يتم استخدام Module._malloc والمؤشرات.
  • \n
\n\n

تمرير السلاسل النصية

\n

مثال لدالة ترجع تحية:

\n\n
// كود C++\nextern "C" {\n    const char* EMSCRIPTEN_KEEPALIVE greet(const char* name) {\n        static std::string msg = "مرحبًا، " + std::string(name) + "!";\n        return msg.c_str();\n    }\n}
\n\n

في JavaS

المدونات

توصيات الكتب