◀Back
Embed C in Java Using GraalWasm
The example below demonstrates how to compile a C function to WebAssembly and run it embedded in a Java application.
Prerequisites
To run the demo, you need the following:
Demo Part
- Put the following C program in a file named 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; }
Note that
floyd
is defined as a separate function and can be exported. - Compile the C code using the most recent version of the Emscripten compiler frontend:
emcc --no-entry -s EXPORTED_FUNCTIONS=_floyd -o floyd.wasm floyd.c
The exported functions must be prefixed by
_
. If you reference that function in, for example, the Java code, the exported name should not contain the underscore.It produces a standalone file floyd.wasm in the current working directory.
-
Add dependencies. The GraalVM SDK Polyglot API can be easily added as a Maven dependency to your Java project. The GraalWasm artifact should be on the Java module or class path too. Add the following set of dependencies to the project configuration file (pom.xml in the case of Maven).
- To add the Polyglot API:
<dependency> <groupId>org.graalvm.polyglot</groupId> <artifactId>polyglot</artifactId> <version>${graalwasm.version}</version> </dependency>
- To add GraalWasm:
<dependency> <groupId>org.graalvm.polyglot</groupId> <artifactId>wasm</artifactId> <version>${graalwasm.version}</version> <type>pom</type> </dependency>
- To add the Polyglot API:
-
Now you can embed this WebAssembly function in a Java application, for example:
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();
- Compile and run this Java application with Maven as usual.