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.

Steps

To use Managed C in your Application, follow these steps:

  1. 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.

  2. 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*
    
  3. Add the BON API Library to Your Project:

    The WasmModule class and the @Alias annotation required for Managed C are part of the BON API library, starting from version 1.6.0.

    implementation("ej.api:bon:1.6.0")
    
  4. Configure your Java Class to Call a Managed C Function:

    Create a class that extends WasmModule. The class must be declared final. Apply the @Alias annotation with the Wasm module name so the SOAR knows which .wasm resource to load:

    import ej.lang.Alias;
    import ej.lang.WasmModule;
    
    @Alias("example")
    public final class Main extends WasmModule {
       ...
    }
    

    Declare an instance method as native and synchronized for 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 main method. 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);
    }
    
  5. Create the C File:

    Create a file named example.c in the directory src/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.

  6. 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, the factorial function is exported with -Wl,--export=factorial.

    Note

    The generated file name example.wasm matches the module name given to the @Alias annotation and is generated in the src/main/resources directory to include it in the MicroEJ classpath.

  7. Build the Application:

    In the terminal, navigate to your application base directory and perform the following steps:

    Edit the file build.gradle.kts and add the location to your prebuilt VEE Port using microejVee(files("/path/to/veeport")).

    Then run the following command to build the Application:

    ./gradlew buildExecutable
    

    Note

    Please refer to the Select a VEE Port section for alternative methods to connect your VEE Port.

  8. Run the Executable:

    Once the Application is built, execute it on your device.

Run the following command:

./gradlew runOnDevice

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: