Dưới đây là bản dịch của văn bản bạn cung cấp sang tiếng Việt (vi):

WebAssembly - Working with C++

# WebAssembly - Làm việc với C++

Xin chào, những người học lập trình tiềm năng! Tôi rất vui mừng được làm hướng dẫn viên của bạn trong hành trình thú vị này vào thế giới của WebAssembly và C++. Là một ai đó đã dạy khoa học máy tính hơn một thập kỷ, tôi có thể đảm bảo với bạn rằng mặc dù chủ đề này có thể看起来 đáng sợ ban đầu, nhưng chúng ta sẽ chia nhỏ nó thành những phần nhỏ dễ nuốt cho cả những người mới bắt đầu. Hãy cuộn lên tay áo và nhảy vào!

## WebAssembly là gì?

Trước khi chúng ta nhảy vào mã, hãy hiểu về WebAssembly là gì. Hãy tưởng tượng bạn đang cố gắng nói chuyện với ai đó không biết ngôn ngữ của bạn. Bạn sẽ cần một người dịch, phải không? Well, WebAssembly giống như người dịch đó cho trình duyệt web của bạn. Nó cho phép các chương trình được viết trong các ngôn ngữ như C++ chạy trong trình duyệt web với tốc độ gần như-native. Đ Cooler không?

## Tại sao lại là C++ với WebAssembly?

Bạn có thể tự hỏi, "Tại sao lại là C++?" Well, C++ giống như cây kéo đa năng của các ngôn ngữ lập trình - nó mạnh mẽ, linh hoạt và đã có từ lâu. Khi kết hợp với WebAssembly, nó cho phép chúng ta mang các ứng dụng hiệu suất cao đến web. Nó giống như涡轮增压 cho trang web của bạn!

## Thiết lập Môi trường Làm Việc

Trước khi chúng ta viết dòng mã đầu tiên, chúng ta cần thiết lập không gian làm việc. Đừng lo lắng, tôi sẽ dẫn bạn qua từng bước:

1. Cài đặt Emscripten: Đây là pháp thuật của chúng ta để chuyển đổi C++ thành WebAssembly.
2. Thiết lập một trình soạn thảo văn bản: Tôi khuyên dùng Visual Studio Code, nhưng bất kỳ trình soạn thảo văn bản nào cũng được.
3. Mở một terminal: Chúng ta sẽ sử dụng này để biên dịch mã của mình.

## Chương Trình WebAssembly Đầu Tiên

Hãy bắt đầu với một chương trình đơn giản "Hello, World!". Đây là mã:

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

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

Bây giờ, hãy phân tích này:

  • #include <emscripten/emscripten.h>: Dòng này bao gồm tệp header của Emscripten, cho phép chúng ta truy cập các hàm liên quan đến WebAssembly.
  • extern "C": Điều này báo cho bộ biên dịch biết sử dụng cách đặt tên theo phong cách C cho các hàm của chúng ta.
  • EMSCRIPTEN_KEEPALIVE: Điều này giống như đặt một biển hiệu "Đừng xóa" trên hàm của chúng ta, đảm bảo rằng nó có sẵn cho JavaScript.
  • void sayHello(): Đây là hàm của chúng ta để in ra lời chào.

Biên Dịch Mã

Đã đến lúc thực hiện phép thuật! Trong terminal của bạn, chạy:

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

Lệnh này có thể trông giống như một lời nguyền từ Harry Potter, nhưng để tôi giải thích:

  • emcc: Đây là bộ biên dịch của chúng ta.
  • hello.cpp: Tệp nguồn của chúng ta.
  • -o hello.html: Điều này tạo ra một tệp HTML mà chúng ta có thể mở trong trình duyệt.
  • Các phần còn lại là các tùy chọn đặc biệt để làm cho WebAssembly hoạt động tốt với JavaScript.

Chạy WebAssembly

Mở tệp hello.html được tạo ra trong trình duyệt, mở console, và gõ:

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

Nếu bạn thấy "Hello, WebAssembly World!" trong console, chúc mừng! Bạn vừa chạy C++ trong trình duyệt của mình!

Một Ví Dụ Phức Tạp Hơn: Máy Tính Fibonacci

Bây giờ chúng ta đã làm quen với, hãy thử một điều gì đó khó khăn hơn - một máy tính số Fibonacci.

#include <emscripten/emscripten.h>

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

Hàm này tính toán số Fibonacci thứ n theo cách đệ quy. Nó không phải là phương pháp hiệu quả nhất, nhưng rất tốt cho việc minh họa!

Biên dịch nó theo cách tương tự như trước, sau đó gọi từ JavaScript như này:

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

Điều này nên in ra số Fibonacci thứ 10 (đó là 55).

Làm Việc với Mảng

Hãy nâng cấp và làm việc với mảng. Đây là một hàm tính tổng của một mảng:

#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;
    }
}

Để sử dụng này từ JavaScript, chúng ta cần làm một chút công việc thêm:

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);  // Nên in ra 15

Điều này có thể trông phức tạp, nhưng chúng ta cơ bản là:

  1. Tạo một mảng trong JavaScript
  2. Phân bổ bộ nhớ trong heap của WebAssembly
  3. Sao chép mảng của chúng ta vào bộ nhớ đó
  4. Gọi hàm của chúng ta
  5. Giải phóng bộ nhớ đã phân bổ

Kết Luận

Chúc mừng! Bạn đã迈出第一步进入WebAssembly和C++的世界。我们已经涵盖了从基本的"Hello, World!"到处理数组的很多内容。记住,学习编码就像学习一门新语言 - 它需要练习和耐心。不要气馁如果你一开始不理解所有的东西。继续尝试,继续编码,最重要的是,继续享受乐趣!

下面是一个总结我们使用的主要方法的表格:

Phương pháp Mô tả
emcc Lệnh biên dịch Emscripten
EMSCRIPTEN_KEEPALIVE Prefix để ngăn chặn hàm bị tối ưu hóa
Module.ccall Phương thức JavaScript để gọi hàm C++
Module._malloc Phân bổ bộ nhớ trong heap của WebAssembly
Module._free Giải phóng bộ nhớ đã phân bổ trong heap của WebAssembly
Module.HEAP32 Xem Int32Array của bộ nhớ WebAssembly

Nhớ rằng, WebAssembly và C++ mở ra một thế giới của khả năng cho phát triển web. Trời cao vời vợi! Tiếp tục mã hóa, tiếp tục học tập, và ai biết? Có lẽ bạn sẽ là người dạy khóa học này trong vài năm tới!

Credits: Image by storyset