返回

使用 GraalWasm 在 Java 中嵌入 C

以下範例展示如何將 C 函數編譯為 WebAssembly,並在 Java 應用程式中嵌入執行。

先決條件

若要執行此示範,您需要以下項目

示範部分

  1. 將以下 C 程式碼放入名為 floyd.c 的檔案中
     #include <stdio.h>
    
     void floyd() {
         int number = 1;
         int rows = 10;
         for (int i = 1; i <= rows; i++) {
             for (int j = 1; j <= i; j++) {
                 printf("%d ", number);
                 ++number;
             }
             printf(".\n");
         }
     }
    
     int main() {
         floyd();
         return 0;
     }
    

    請注意,floyd 定義為個別的函數,且可以匯出。

  2. 使用最新版本的 Emscripten 編譯器前端 來編譯 C 程式碼
     emcc --no-entry -s EXPORTED_FUNCTIONS=_floyd -o floyd.wasm floyd.c
    

    匯出的函數必須以 _ 作為前綴。如果例如在 Java 程式碼中參考該函數,則匯出的名稱不應包含底線。

    這會在目前的工作目錄中產生一個獨立的 floyd.wasm 檔案。

  3. 新增相依性。GraalVM SDK Polyglot API 可以輕鬆地以 Maven 相依性的形式新增至您的 Java 專案。GraalWasm 成品也應位於 Java 模組或類別路徑上。將以下一組相依性新增至專案組態檔案 (在使用 Maven 的情況下為 pom.xml)。

    • 若要新增 Polyglot API
        <dependency>
            <groupId>org.graalvm.polyglot</groupId>
            <artifactId>polyglot</artifactId> 
            <version>${graalwasm.version}</version>
        </dependency>
      
    • 若要新增 GraalWasm
        <dependency>
            <groupId>org.graalvm.polyglot</groupId>
            <artifactId>wasm</artifactId> 
            <version>${graalwasm.version}</version>
            <type>pom</type>
        </dependency>
      
  4. 現在您可以將此 WebAssembly 函數嵌入 Java 應用程式中,例如

     import org.graalvm.polyglot.*;
     import org.graalvm.polyglot.io.ByteSequence;
    
     // Load the WebAssembly contents into a byte array
     byte[] binary = Files.readAllBytes(Path.of("path", "to", "wasm", "file", "floyd.wasm"));
    
     // Setup context
     Context.Builder contextBuilder = Context.newBuilder("wasm").option("wasm.Builtins", "wasi_snapshot_preview1");
     Source.Builder sourceBuilder = Source.newBuilder("wasm", ByteSequence.create(binary), "example");
     Source source = sourceBuilder.build();
     Context context = contextBuilder.build();
    
     // Evaluate the WebAssembly module
     context.eval(source);
    
     // Execute the floyd function
     context.getBindings("wasm").getMember("example").getMember("_initialize").executeVoid();
     Value mainFunction =context.getBindings("wasm").getMember("example").getMember("floyd");
     mainFunction.execute();
     context.close();
    
  5. 像往常一樣使用 Maven 編譯並執行此 Java 應用程式。

與我們聯繫