Skip to content


Repository files navigation

fastFFI: Modern and Efficient FFI for Java and C++

Basically, fastFFI has three components:

  • FFI: DSL and API used to develop FFI applications.
  • Annotation Processor: the code generator for FFI.
  • LLVM4JNI: LLVM4JNI has two submodules:
    • LLVM4JNI: a tool that translates LLVM bitcode into Java bytecode.
    • LLVM4JNI Runtime: the runtime component used by generated bytecode.

An FFI application must include ffi and llvm4jni-runtime in its class path as runtime dependency.


  1. Checkout source code

    git clone <path-to-fastffi> fastffi
  2. Prepare building environment

    export LLVM11_HOME=<path-to-llvm-11>

    LLVM11_HOME should point to the home of LLVM 11. In Ubuntu, it is at /usr/lib/llvm-11. Basically, the build procedure the following binary:

    • $LLVM11_HOME/bin/clang++
    • $LLVM11_HOME/bin/ld.lld
    • $LLVM11_HOME/lib/cmake/llvm
  3. Use fastFFI with Maven.

        <!-- The FFI annotation -->
        <!-- The FFI annotation processor for code generation -->
        <!-- The runtime component of LLVM4JNI -->
  4. Use maven to build your applications.

    The generated code, including Java and C++ code, is available in <project.dir>/target/generated-source/annotations


A Java programming language compiler must support standard options in the format -Akey[=value]. fastFFI provides the following options:

  1. fastffi.handleException: whether generating code to handle C++ exceptions
    • default value: false
  2. fastffi.manualBoxing: using new Integer() or new Long() to box a primitive integer.
    • default value: true
    • Auto boxing uses Integer.valueOf or Long.valueOf, which cannot be properly handled by the escape analysis of C2 compiler.
  3. fastffi.strictTypeCheck
    • default value: false
  4. fastffi.nullReturnValueCheck
    • default value: true
    • insert additional null check for native pointers
  5. fastffi.cxxOutputLocation
    • default value: CLASS_OUTPUT
  6. fastffi.traceJNICalls
    • default value: false
    • generate stuffs to trace the invocations of JNI wrappers
  7. fastffi.compactFFINames
    • default value: true
    • generate compact FFI wrapper type names, non-compact names will benefit debugging, but increase the binary size



Build Mac OS

  1. Install a JDK (JDK 8 and 11)

  2. Install LLVM 11, Maven and CMake

    brew install llvm@11 cmake maven
  3. Set ENV

    export LLVM11_HOME=/usr/local/opt/llvm@11