Getting Started
Welcome to the Managed C Getting Started Guide. This guide is designed to help application developers quickly get up to speed with Managed C. You’ll learn how to set up your environment and build your first Managed C application. Let’s get started!
Prerequisites
Before you begin, ensure that the following elements are available on your workstation:
A pre-built VEE Port using an Architecture v9.0.0 or higher.
A pre-built VEE Port using an Architecture v9.0.0 or higher.
MMM CLI (Command Line Interface), for building the demo module from command line.
Steps
To use Managed C in your Application, follow these steps:
Install WASI-SDK:
Download the WASI SDK version 25.
Extract it at the location of your choice on your machine. This location will be referred to as
[path_to_wasi_sdk]in the rest of the documentation.Create a Standalone Application Project:
In the terminal, run the following command:
git clone https://github.com/MicroEJ/Tool-Project-Template-Application.git cd Tool-Project-Template-Application rm -rf .git*
mmm init -Dskeleton.org=com.is2t.easyant.skeletons -Dskeleton.module=firmware-singleapp -Dskeleton.rev=2.+ -Dproject.org=com.mycompany -Dproject.module=myproject -Dproject.rev=1.0.0 -Dskeleton.target.dir=myproject
Note
The project property values can be adjusted according to your needs. For more details, refer to the MMM CLI init command documentation.
Note
If you’re using PowerShell, prepend the token --% before passing the arguments to prevent PowerShell from parsing them. For example:
mmm init --% -D....Add the BON API Library to Your Project:
The
WasmModuleclass and the@Aliasannotation required for Managed C are part of the BON API library, starting from version1.6.0.implementation("ej.api:bon:1.6.0")
<dependency org="ej.api" name="bon" rev="1.6.0"/>
Configure your Java Class to Call a Managed C Function:
Create a class that extends
WasmModule. The class must be declaredfinal. Apply the@Aliasannotation with the Wasm module name so the SOAR knows which.wasmresource to load:import ej.lang.Alias; import ej.lang.WasmModule; @Alias("example") public final class Main extends WasmModule { ... }
Declare an instance method as
nativeandsynchronizedfor each Managed C function to call from Java:import ej.lang.Alias; import ej.lang.WasmModule; @Alias("example") public final class Main extends WasmModule { ... public native synchronized int factorial(int n); }
Finalize your application’s
mainmethod. Instantiate the module first to allocate its linear memory, then call the Managed C function on the instance:import ej.lang.Alias; import ej.lang.WasmModule; @Alias("example") public final class Main extends WasmModule { public static void main(String[] args) { Main myApp = new Main(); System.out.println("factorial(10) = " + myApp.factorial(10)); } public native synchronized int factorial(int n); }
Create the C File:
Create a file named
example.cin the directorysrc/main/c:int factorial(int n) { if (n == 1) { return 1; } else { return n * factorial(n - 1); } }
Note
The name and signature of the Managed C function in the C file must match the instance native Java method.
Compile the C File to WebAssembly:
In the terminal, navigate to your application base directory and run the following command to compile the C code to WebAssembly:
[path_to_wasi_sdk]/bin/clang -nostdlib -mcpu=mvp -O3 -z stack-size=4096 -Wl,--no-entry -Wl,--stack-first -Wl,--export=__heap_base -Wl,--allow-undefined -Wl,--export=factorial src/main/c/example.c -o src/main/resources/example.wasm
Note
To call a Managed C function from Java code, you need to export it using the
-Wl,--export=[function_name]linker option. In this case, thefactorialfunction is exported with-Wl,--export=factorial.Note
The generated file name
example.wasmmatches the module name given to the@Aliasannotation and is generated in thesrc/main/resourcesdirectory to include it in the MicroEJ classpath.Build the Application:
In the terminal, navigate to your application base directory and perform the following steps:
Edit the file
build.gradle.ktsand add the location to your prebuilt VEE Port usingmicroejVee(files("/path/to/veeport")).Then run the following command to build the Application:
./gradlew buildExecutableNote
Please refer to the Select a VEE Port section for alternative methods to connect your VEE Port.
Run the following command to build the Application:
mmm build -Dplatform-loader.target.platform.dir=<prebuilt_veeport_path>/source
Note
Replace
<prebuilt_veeport_path>with the location of your prebuilt VEE Port. See Select a VEE Port section for alternative ways to connect your VEE Port.Run the Executable:
Once the Application is built, execute it on your device.
Run the following command:
./gradlew runOnDevice
Refer to Run on the Device section.
After deployment, you should see the following output:
factorial(10) = 3628800
Congratulations! You have successfully run your first Managed C code. You are now ready to explore how to build more complex Managed C projects.
For further details, refer to the following sub-sections:
Compiling your Project: Instructions on how to compile and link an existing C or C++ project to WebAssembly.
Bind Java code and Managed C Code: Information on how to seamlessly link your Java code and Managed C code.
Linear memory: Instructions to configure WebAssembly Linear memory.
WASI Library: Explore WASI, the WebAssembly System Interface implemented by MicroEJ.
Troubleshooting: Help with resolving common issues when working with Managed C.
