返回

使用 GraalWasm 将 C 嵌入 Java

以下示例演示如何将 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 多语言 API 可以轻松地作为 Maven 依赖项添加到您的 Java 项目中。GraalWasm 工件也应该位于 Java 模块或类路径上。将以下依赖项集添加到项目配置文件(对于 Maven 来说是 pom.xml)。

    • 添加多语言 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 应用程序。

联系我们