WebAssembly - Работа с C++

Здравствуйте,野心勃勃的程序员们!我很高兴能成为您在这个激动人心的WebAssembly和C++世界中的向导。作为一个教授计算机科学超过十年的老手,我可以向您保证,尽管这个主题一开始可能看起来令人生畏,但我们将把它分解成小块,即使是完全的初学者也能消化。那么,让我们卷起袖子,跳进去吧!

WebAssembly - Working with C++

Что такое WebAssembly?

Прежде чем мы перейдем к коду, давайте поймем, что такое WebAssembly. Представьте, что вы пытаетесь поговорить с кем-то, кто не знает вашего языка. Вам понадобится переводчик, не так ли? Ну, WebAssembly как раз и является таким переводчиком для вашего веб-браузера. Он позволяет программам, написанным на языках, таких как C++, работать в веб-браузерах с了近原生速度. Круто, да?

Why C++ с WebAssembly?

Вы можете задаться вопросом: "Почему C++?" Ну, C++ как швейцарский армейский нож среди языков программирования - он мощный, гибкий и уже давно используется. В сочетании с WebAssembly он позволяет намBring высокопроизводительные приложения в веб. Это как turbopropeler ваш веб-сайт!

Настройка нашего окружения

Прежде чем мы напишем первую строку кода, нам нужно настроить нашу рабочую среду. Не волнуйтесь, я проведу вас через это шаг за шагом:

  1. Установите Emscripten: Это наша палочка-чародейка, которая превращает C++ в WebAssembly.
  2. Настройте текстовый редактор: Я рекомендую Visual Studio Code, но любой текстовый редактор подойдет.
  3. Откройте терминал: Мы будем использовать его для компиляции нашего кода.

Наш первый WebAssembly Программа

Давайте начнем с простой программы "Hello, World!". Вот код:

#include <emscripten/emscripten.h>
#include <stdio.h>

extern "C" {
EMSCRIPTEN_KEEPALIVE
void sayHello() {
printf("Hello, WebAssembly World!\n");
}
}

Теперь давайте разберем это:

  • #include <emscripten/emscripten.h>: Эта строка включает заголовочный файл Emscripten, давая нам доступ к функциям, связанным с WebAssembly.
  • extern "C": Это говорит компилятору использовать стили naming для наших функций.
  • EMSCRIPTEN_KEEPALIVE: Это как putting a "Do Not Erase" sign на нашу функцию, обеспечивая, что она доступна для JavaScript.
  • void sayHello(): Это наша функция, которая выводит приветствие.

Компиляция нашего кода

Пришло время wave нашей magic wand! В вашем терминале, запустите:

emcc hello.cpp -o hello.html -s NO_EXIT_RUNTIME=1 -s "EXPORTED_RUNTIME_METHODS=['ccall']"

Эта команда может показаться как заклинание из Harry Potter, но позвольте мне объяснить:

  • emcc: Это наш компилятор.
  • hello.cpp: Наш исходный файл.
  • -o hello.html: Это создает HTML-файл, который мы можем открыть в браузере.
  • Оставшиеся флаги делают наш WebAssembly友好 с JavaScript.

Запуск нашего WebAssembly

Откройте сгенерированный hello.html в вашем браузере, откройте консоль и введите:

Module.ccall('sayHello', null, null, null);

Если вы видите "Hello, WebAssembly World!" в консоли,恭喜您! Вы только что запустили C++ в вашем браузере!

Более сложный пример: Calculator Fibonacci

Теперь, когда мы намочили ноги, давайте попробуем что-то по сложнее - calculator для вычисления чисел Фибоначчи.

#include <emscripten/emscripten.h>

extern "C" {
EMSCRIPTEN_KEEPALIVE
int fibonacci(int n) {
if (n <= 1) return n;
return fibonacci(n-1) + fibonacci(n-2);
}
}

Эта функция вычисляет n-е число Фибоначчи рекурсивно. Это не самый эффективный метод, но он великолепен для демонстрации!

Скомпилируйте его так же, как и раньшеПотом вызовите его из JavaScript следующим образом:

console.log(Module.ccall('fibonacci', 'number', ['number'], [10]));

Это должно вывести 10-е число Фибоначчи (которое равно 55, кстати).

Работа с массивами

Давайте поднимем уровень и поработаем с массивами. Вот функция, которая вычисляет сумму элементов массива:

#include <emscripten/emscripten.h>

extern "C" {
EMSCRIPTEN_KEEPALIVE
int sumArray(int* arr, int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
sum += arr[i];
}
return sum;
}
}

Чтобы использовать это из JavaScript, нам нужно сделать немного больше работы:

let arr = new Int32Array([1, 2, 3, 4, 5]);
let buffer = Module._malloc(arr.length * arr.BYTES_PER_ELEMENT);
Module.HEAP32.set(arr, buffer >> 2);
let sum = Module.ccall('sumArray', 'number', ['number', 'number'], [buffer, arr.length]);
Module._free(buffer);
console.log(sum);  // Should print 15

Это может показаться сложным, но мы essentially:

  1. Создаем массив в JavaScript
  2. Выделяем память в кэше WebAssembly
  3. Копируем наш массив в эту память
  4. Вызываем нашу функцию
  5. Освобождаем выделенную память

Заключение

Поздравляю! Вы сделали свои первые шаги в мир WebAssembly с C++. Мы covered много ground, от базового "Hello, World!" до работы с массивами. Помните, что учиться программировать как учиться новому языку - это требует практики и терпения. Не отчаивайтесь, если вы не понимаете все сразу. Продолжайте экспериментировать, продолжайте программировать и, самое главное, продолжайте получать удовольствие!

Вот таблица, резюмирующая основные методы, которые мы использовали:

Метод Описание
emcc Команда компилятора Emscripten
EMSCRIPTEN_KEEPALIVE Мacro для предотвращения оптимизации функции
Module.ccall Метод JavaScript для вызова функций C++
Module._malloc Выделение памяти в кэше WebAssembly
Module._free Освобождение выделенной памяти в кэше WebAssembly
Module.HEAP32 Int32Array view của WebAssembly memory

Помните, WebAssembly и C++ открывают мир возможностей для веб-разработки. Небо - это limit! Продолжайте программировать, продолжайте учиться, и кто знает? Может быть, через несколько лет вы будете тем, кто преподаёт этот курс!

Credits: Image by storyset