The GraalVM SDK Native Image API allows to customize the native image generation, i.e., the ahead-of-time compilation of Java code to standalone executables
—
Comprehensive C interoperability framework providing type-safe integration between Java and C code. Enables direct function calls, struct mapping, pointer operations, and memory management without JNI overhead.
Direct Java-to-C function calls bypassing JNI protocol for maximum performance.
/**
* Maps Java methods to C functions for direct calls
*/
@interface CFunction {
/** C function name (defaults to Java method name) */
String value() default "";
/** C library name containing the function */
String library() default "";
}
/**
* Marks Java methods as VM entry points accessible from C
*/
@interface CEntryPoint {
/** C function name for the entry point */
String name() default "";
/** Documentation string */
String documentation() default "";
}
/**
* Specifies C library dependencies
*/
@interface CLibrary {
/** Library name or path */
String value();
}
/**
* Pointer to C functions - marker interface for function pointers
*/
interface CFunctionPointer extends CodePointer, RelocatedPointer {}
/**
* Relocatable function pointer
*/
interface CodePointer extends PointerBase {}
/**
* Relocated code pointer support
*/
interface RelocatedPointer extends CodePointer {}Usage Examples:
// Direct C function calls
@CFunction
static native int strlen(CCharPointer str);
@CFunction("custom_malloc")
static native VoidPointer allocateMemory(int size);
@CLibrary("mylib")
@CFunction
static native void processData(CIntPointer data, int length);
// Entry points callable from C
@CEntryPoint(name = "java_callback")
static int callbackFromC(int value) {
return value * 2;
}
// Function pointers
interface MathFunction extends CFunctionPointer {
@InvokeCFunctionPointer
double apply(double x);
}
// Using function pointers
MathFunction sinFunc = /* get function pointer */;
double result = sinFunc.apply(3.14159);Interface-based mapping of C structures with type-safe field access.
/**
* Maps Java interfaces to C structures
*/
@interface CStruct {
/** C struct name (defaults to interface name) */
String value() default "";
}
/**
* Maps interface methods to C struct fields
*/
@interface CField {
/** C field name (defaults to method name without get/set prefix) */
String value() default "";
}
/**
* Computes address of struct fields
*/
@interface CFieldAddress {
/** Field name */
String value();
}
/**
* Computes offset of struct fields
*/
@interface CFieldOffset {
/** Field name */
String value();
}
/**
* Bitfield support within structs
*/
@interface CBitfield {
/** Bit position */
int position();
/** Number of bits */
int width();
}
/**
* Low-level struct operations
*/
interface RawStructure extends PointerBase {
/** Read raw bytes from the structure */
byte readByte(int offset);
/** Write raw bytes to the structure */
void writeByte(int offset, byte value);
}Usage Examples:
// Define a C struct mapping
@CStruct("point")
interface Point extends PointerBase {
@CField("x")
int getX();
@CField("x")
void setX(int value);
@CField("y")
int getY();
@CField("y")
void setY(int value);
}
// Use the struct
Point point = StackValue.get(Point.class);
point.setX(10);
point.setY(20);
// Field operations
@CFieldAddress("x")
static native CIntPointer getXAddress(Point point);
@CFieldOffset("y")
static native int getYOffset();
// Bitfields
@CStruct
interface Flags extends PointerBase {
@CBitfield(position = 0, width = 1)
boolean getEnabled();
@CBitfield(position = 0, width = 1)
void setEnabled(boolean value);
@CBitfield(position = 1, width = 3)
int getPriority();
@CBitfield(position = 1, width = 3)
void setPriority(int value);
}Comprehensive type-safe pointer system for C interoperability.
/**
* Base interface for word-sized values
*/
interface WordBase {
/** Convert to raw long value */
long rawValue();
}
/**
* Base interface for all pointer types
*/
interface PointerBase extends ComparableWord {
/** Check if pointer is null */
boolean isNull();
/** Check if pointer is non-null */
boolean isNonNull();
}
/**
* Generic word-sized pointer
*/
interface WordPointer extends PointerBase {
/** Read word value at offset */
WordBase read(int index);
/** Write word value at offset */
void write(int index, WordBase value);
}
/**
* Pointer to void (opaque data)
*/
interface VoidPointer extends PointerBase {}
/**
* Typed pointers for primitive types
*/
interface CCharPointer extends PointerBase {
byte read();
void write(byte value);
byte read(int index);
void write(int index, byte value);
CCharPointer addressOf(int index);
}
interface CIntPointer extends PointerBase {
int read();
void write(int value);
int read(int index);
void write(int index, int value);
CIntPointer addressOf(int index);
}
interface CLongPointer extends PointerBase {
long read();
void write(long value);
long read(int index);
void write(int index, long value);
CLongPointer addressOf(int index);
}
interface CFloatPointer extends PointerBase {
float read();
void write(float value);
float read(int index);
void write(int index, float value);
CFloatPointer addressOf(int index);
}
interface CDoublePointer extends PointerBase {
double read();
void write(double value);
double read(int index);
void write(int index, double value);
CDoublePointer addressOf(int index);
}Usage Examples:
// Pointer operations
CIntPointer intPtr = StackValue.get(CIntPointer.class);
intPtr.write(42);
int value = intPtr.read();
// Array operations
CIntPointer array = StackValue.get(10, CIntPointer.class);
for (int i = 0; i < 10; i++) {
array.write(i, i * i);
}
// Pointer arithmetic
CCharPointer base = /* ... */;
CCharPointer offset = base.addressOf(5);
// Null checks
if (ptr.isNonNull()) {
int data = ptr.read();
}Utilities for converting between Java and C types.
/**
* Java/C type conversion utilities
*/
class CTypeConversion {
/** Convert Java string to C string */
static CCharPointer toCString(String javaString);
/** Convert C string to Java string */
static String toJavaString(CCharPointer cString);
/** Convert Java byte array to C pointer */
static CCharPointer toCBytes(byte[] javaBytes);
/** Convert C pointer to Java byte array */
static byte[] toJavaBytes(CCharPointer cBytes, int length);
/** Create pinned UTF-8 C string from Java string */
static CTypeConversion.CCharPointerHolder toCString(String javaString, Charset charset);
}
/**
* Holder for C strings with automatic cleanup
*/
interface CTypeConversion.CCharPointerHolder extends AutoCloseable {
/** Get the C string pointer */
CCharPointer get();
/** Release the C string */
void close();
}
/**
* Size computation for C types
*/
@interface SizeOf {
/** C type name */
String value();
}
/**
* Type-safe pointer to specific types
*/
@interface CPointerTo {
/** Target type */
Class<?> value();
}Usage Examples:
// String conversion
String javaStr = "Hello, World!";
try (CTypeConversion.CCharPointerHolder holder = CTypeConversion.toCString(javaStr)) {
CCharPointer cStr = holder.get();
int length = strlen(cStr);
System.out.println("C string length: " + length);
}
// Byte array conversion
byte[] javaBytes = {1, 2, 3, 4, 5};
CCharPointer cBytes = CTypeConversion.toCBytes(javaBytes);
// Size queries
@SizeOf("struct point")
static native int pointSize();
// Type-safe pointers
@CPointerTo(Point.class)
interface PointPointer extends PointerBase {
Point read();
void write(Point value);
}Mapping of C constants and enums to Java.
/**
* Maps Java methods to C constants
*/
@interface CConstant {
/** C constant name */
String value() default "";
}
/**
* Marks interfaces as C enum types
*/
@interface CEnum {
/** C enum name */
String value() default "";
}
/**
* Maps to individual enum constants
*/
@interface CEnumConstant {
/** C enum constant name */
String value();
}
/**
* Lookup method for C enum values
*/
@interface CEnumLookup {}
/**
* Conversion from Java enum to C enum value
*/
@interface CEnumValue {}Usage Examples:
// C constants
@CConstant("EAGAIN")
static native int eagain();
@CConstant("PIPE_BUF")
static native int pipeBufferSize();
// C enums
@CEnum("color")
enum Color {
@CEnumConstant("COLOR_RED") RED,
@CEnumConstant("COLOR_GREEN") GREEN,
@CEnumConstant("COLOR_BLUE") BLUE;
@CEnumLookup
static native Color fromValue(int value);
@CEnumValue
native int getValue();
}
// Using enums
Color red = Color.RED;
int redValue = red.getValue();
Color fromC = Color.fromValue(cEnumValue);Compilation context and header configuration for C interop.
/**
* Defines C compilation context and library dependencies
*/
@interface CContext {
/** Header files to include */
Class<? extends CContext.Directives>[] value();
}
/**
* Specifies C header files to be parsed
*/
@interface CHeader {
/** Header file names or paths */
String[] value();
}
/**
* Type modifiers for C types
*/
@interface CConst {}
@interface CUnsigned {}Usage Examples:
// Context definition
@CContext(MyDirectives.class)
public class MyCInterop {
static class MyDirectives implements CContext.Directives {
@Override
public List<String> getHeaderFiles() {
return Arrays.asList("<stdio.h>", "<stdlib.h>", "myheader.h");
}
@Override
public List<String> getLibraries() {
return Arrays.asList("mylib");
}
}
}
// Header inclusion
@CHeader({"<unistd.h>", "<sys/types.h>"})
public class UnixInterop {
@CFunction
static native int getpid();
@CFunction
static native CCharPointer getenv(CCharPointer name);
}
// Type modifiers
@CStruct
interface FileInfo extends PointerBase {
@CField
@CConst
CCharPointer getName();
@CField
@CUnsigned
int getSize();
}This C interoperability framework enables seamless integration between Java and C code while maintaining type safety and performance. It eliminates JNI overhead through direct function calls and provides comprehensive support for C data structures, memory management, and type conversions.
Install with Tessl CLI
npx tessl i tessl/maven-org-graalvm-sdk--nativeimage