# WasmEdge 0.16.1 版本 C API 簡單看過


## 正文

參考 [C API 0.16.1 Documentation](https://wasmedge.org/docs/embed/c/reference/latest/)。

WebAssembly 是一個開放標準，所以有很多不同的團隊開發了各自的 Runtime（執行環境），它們就像是瀏覽器界的 Chrome、Firefox 和 Safari。

目前主流的非瀏覽器 Runtime 包括：

* Wasmtime: 由 Bytecode Alliance（字節碼聯盟，成員包括 Fastly, Intel, Mozilla 等）開發，非常強調安全性與標準符合
* Wasmer: 標榜「能在任何地方執行」，且支援多種不同的編譯後端（LLVM, Cranelift, Singlepass）
* WAMR (WebAssembly Micro Runtime): 由 Intel 開發，專門為資源極其有限的物聯網（IoT）或嵌入式設備設計，體積非常小
* Bun / Node.js: 它們內部也都有整合 WASM 引擎（如 V8），讓你在 JS 環境中跑 WASM

所有的 WebAssembly Runtime 都必須遵守 W3C WebAssembly Specification。這份規範定義了執行 WASM 的四個標準階段。

## Configuration

Config 會有不同的設定像是

* BulkMemoryOperations: 批次記憶體操作
* SIMD: 單指令流多資料流（加速運算，如影像處理）
* MultiMemories: 支援一個模組有多個記憶體區塊
* Threads: 支援多線程

```cpp
WasmEdge_ConfigureContext *ConfCxt = WasmEdge_ConfigureCreate();
```
  
在 WasmEdge 中，大部分的物件（如 Loader、Validator、Executor）在建立時，都可以傳入這個 `ConfigureContext` 來決定不同設定。

## VM

如果你不使用 VM，你得手動建立 Loader（讀取檔案）、Validator（檢查正確性）和 Executor（執行）。但有了 VM，你只需要把 Configuration 丟進去，它內部會自動幫你準備好這一切。

文件有幾個用 VM 的例子：

* `WasmEdge_VMRunWasmFromFile` 主要用這個 API 執行，他就是一次性包含載入、驗證、實例化、執行，缺點是只能執行一次
* 第二種是你真的一個一個執行，先 Load -> Validate -> Instantiate -> Execute，優點是可以執行很多次
  * `WasmEdge_VMLoadWasmFromFile`: Load
  * `WasmEdge_VMValidate`: Validate
  * `WasmEdge_VMInstantiate`: Instantiate
  * `WasmEdge_VMExecute`: Execute

![alt text](image.png)

你甚至可以 VM 客製化：

```cpp
// 1. 準備工具
WasmEdge_ConfigureContext *ConfCxt = WasmEdge_ConfigureCreate();
WasmEdge_StoreContext *StoreCxt = WasmEdge_StoreCreate();

// 2. 組裝 VM (把工具裝進去)
WasmEdge_VMContext *VMCxt = WasmEdge_VMCreate(ConfCxt, StoreCxt);

// 3. 獲取效能數據 (這只是個「觀察窗」，所有權還是在 VM 身上)
WasmEdge_StatisticsContext *StatCxt = WasmEdge_VMGetStatisticsContext(VMCxt);

// 4. 清理現場 (順序很重要)
WasmEdge_VMDelete(VMCxt);         // 先刪 VM
WasmEdge_StoreDelete(StoreCxt);     // 再刪你當初借給它的 Store
WasmEdge_ConfigureDelete(ConfCxt); // 最後刪配置
```

### Built-in Module

```cpp
WasmEdge_ConfigureContext *ConfCxt = WasmEdge_ConfigureCreate();
// 關鍵 API：增加主機註冊項目
WasmEdge_ConfigureAddHostRegistration(ConfCxt, WasmEdge_HostRegistration_Wasi);
```

如上可以直接設定，你不需要另外下載檔案，這些功能已經寫在 WasmEdge 的核心裡了，你只需要在建立 VM 前「打勾」說你要用就好。

### 註冊模組

```cpp
// 1. 建立一個空的 VM
WasmEdge_VMContext *VMCxt = WasmEdge_VMCreate(NULL, NULL);

// 2. 手動建立一個 WASI 模組實例 (這只是一個範例，也可以是你自定義的模組)
WasmEdge_ModuleInstanceContext *WasiModule = WasmEdge_ModuleInstanceCreateWASI(...);

// 3. 重點：將模組註冊進 VM
WasmEdge_Result Res = WasmEdge_VMRegisterModuleFromImport(VMCxt, WasiModule);

// ... 執行 WASM ...

// 4. 清理現場：兩邊都要手動刪除
WasmEdge_VMDelete(VMCxt);
WasmEdge_ModuleInstanceDelete(WasiModule); // 這一行不能漏掉！
```

如上，用 `WasmEdge_VMRegisterModuleFromImport` 將模組註冊進 VM。

---

你也可以使用不同函式註冊模組：

* `WasmEdge_VMRegisterModuleFromFile`（從檔案）
* `WasmEdge_VMRegisterModuleFromBytes`（從記憶體）
* `WasmEdge_VMRegisterModuleFromASTModule`（從編譯後的 AST 物件）

使用 `WasmEdge_VMExecuteRegistered` 指定「模組名 + 函式名」來執行函式。

### Asynchronous Execution

之前的 `Execute` 函式都是 Blocking 的，WasmEdge 也提供 Async 的執行，當你發起非同步執行時，API 會立即回傳一個 `WasmEdge_Async` 指標。

拿到他你可以：

1. `WasmEdge_AsyncWait`
2. `WasmEdge_AsyncWaitFor`
3. `WasmEdge_AsyncCancel`
4. `WasmEdge_AsyncGetReturns`

### 獲得 VM 的模組

1. `WasmEdge_VMGetRegisteredModule`: 根據名稱拿到模組
2. `WasmEdge_VMGetActiveModule`: 只拿到正在跑的 Active Module

## Runtime

可以參考文件他有一個例子完全使用自己的東西跑 WASM - [WASM Execution Example Step-By-Step](https://wasmedge.org/docs/embed/c/reference/latest/#wasm-execution-example-step-by-step)

### Loader

它是把二進位檔案（.wasm）翻譯成 WasmEdge 內部看得懂的數據結構（叫做 AST Module）。

常見 API 像是 `WasmEdge_LoaderParseFromFile` 或 `WasmEdge_LoaderParseFromBytes`。

### Validator

Validator 讓 WASM 可以在不需要作業系統層級防護（如進程隔離）的情況下，保證執行過程是 100% 安全的。

### Executor

真正會動到 CPU 指令、處理運算邏輯、並管理呼叫棧（Call Stack）的地方。

### AST Module

它是 WASM 二進位碼在記憶體中的結構化表現。它還不是一個「活的」程式，只是一份詳盡的說明書，紀錄了有哪些函式、哪些變數。

### Serializer

這是 Loader 的反向操作，把記憶體中的 `AST Module` 重新轉回二進位的 `.wasm` 格式，如果你對 WASM 進行了 AOT（Ahead-of-Time）編譯優化，你可以用 Serializer 把優化後的結果存成檔案，下次讀取就極快。

### Store

Store 是 WasmEdge 的運行時數據庫。它紀錄了所有已經實例化（Instantiated）的物件。

並且紀錄模組資訊，像是：

* Module Instances：已經跑起來的模組
* Global Variables：現在這些全域變數的值是多少
* Memory：目前的記憶體數據
* Tables：函式索引表

### Instance

介紹 WASM 的五大基本元件在運行時的 Context：

* Module Instance：整個模組的運行實體
* Function Instance：一個可以被呼叫的函式
* Table / Memory / Global Instance：運行中的表格、記憶體、全域變數

### Host Functions (主機函式)

教你如何定義一個 C 函式，並把它包裝成 WASM 看得懂的 `WasmEdge_FunctionInstance`。

當 WASM 呼叫你的 C 函式時，會傳入一個 `CallingFrameContext`，透過這個「框架」，你的 C 函式可以反過來去讀取 WASM 的記憶體，WASM 傳一個記憶體地址給你，你的 C 函式透過 Calling Frame 找到那塊地址，把字串印出來。

WasmEdge 內部已經實現了一套標準的 Host Functions (Built-in Modules)。當你在 Rust 或 C 編譯 WASM 時，只要使用了 printf 或 println!，編譯器就會自動把它連結到 WASM 的 import "wasi_snapshot_preview1" 裡。

### Plug-ins (插件)

如果你想讓你的 WasmEdge 支援 TensorFlow、OpenCV 或 HTTPS，但你不想自己動手寫一堆 Host Functions，這就是為你準備的。

* 你把插件檔案放到特定的資料夾
* 程式啟動時呼叫 `WasmEdge_PluginLoadWithDefaultPaths()`
* WasmEdge 會自動掃描並載入這些功能

你可以直接使用官方提供的 wasmedge_rustls（網路）、wasmedge_process（系統指令）或 wasmedge_nn（AI 推理）插件。

