Skip to content
Samuel Audet edited this page Sep 26, 2018 · 1 revision

Basic Architecture of JavaCPP

Introduction

The three main components of JavaCPP are the Builder, the Loader, and the Pointer. The first one takes care of parsing C/C++ header files and building native libraries at compile time, the second gets invoked at runtime to load these libraries, and extract them from JAR files into the cache if necessary, while the third is responsible for providing an API to call native functions and access native variables.

The Builder

The execution of the Builder typically consists of 4 stages, either as a standalone command line utility or via a plugin such as BuildMojo for Maven:

  1. Runs optional external build scripts, such as cppbuild.sh from the JavaCPP Presets,
    • Outputs native libraries (.so, .dylib, .dll, etc),
  2. Runs the Parser on the given InfoMap and the header files listed in the @Platform annotation,
    • Outputs native Java interfaces (.java), as explained further in the Mapping Recipes,
  3. Runs the Generator on the Java interfaces,
    • Outputs native JNI code in C++ (.cpp, .cu, .mm, etc),
  4. Runs the native C++ compiler (GCC, Clang, MSVC, NVCC, etc) on the JNI code,
    • Outputs native libraries containing JNI wrappers, optionally archived in a JAR file.

The Loader

When executing Loader.load() at runtime, either manually or as part of the automatically generated static { } blocks, it does 3 things automatically:

  1. Searches the class path for the native libraries, including all dependencies,
  2. Extracts them, if found in JAR files, to its cache by default in ~/.javacpp/cache,
  3. Loads all the libraries via System.load(), or System.loadLibrary() if not found on the class path.

The Pointer

Users access through subclasses of Pointer all native arrays, functions, and objects of class, struct, or union types. The following subclasses are provided by default for basic data types:

  • BytePointer, ShortPointer, IntPointer, LongPointer, CLongPointer, SizeTPointer, FloatPointer, DoublePointer, BoolPointer, CharPointer, PointerPointer, FunctionPointer

Pointer calls all functions, and reads and writes all variables via JNI, which introduces overhead. For this reason, JavaCPP also comes with the indexer package, mapping native data to multidimensional arrays (aka tensors, including unsigned integer types and half floats) via sun.misc.Unsafe, to support memory regions larger than 2 GB, falling back on NIO buffers only when not supported such as on Android.

There is also PointerScope to manage more easily and efficiently the native memory and resources used by a group of Pointer objects.