Pointer<T> is a generic type-safe container for a single memory location. It replaces raw FFM MemorySegment access for simple out-parameters or pointers.
- Type Safety: Avoids manual byte offsets.
- Carrier Mappings: Seamlessly wraps reading/writing back and forth between native carriers and high-level Java boxed types.
import io.github.undeffineddev.ffmkit.memory.MemoryScope;
import io.github.undeffineddev.ffmkit.memory.Pointer;
import java.lang.foreign.MemorySegment;
try (MemoryScope scope = MemoryScope.open()) {
// Allocate an initialized pointer (int* = 10)
Pointer<Integer> ptr = Pointer.of(scope, 10);
// Or zero-initialized via the scope helpers
// Pointer<Integer> ptr = scope.allocateInt();
// ptr.set(42);
// Read value
int val = ptr.get();
// Access underlying MemorySegment for downcalls
MemorySegment rawSeg = ptr.segment();
}| Factory | Native type |
|---|---|
Pointer.of(scope, int) |
int* |
Pointer.of(scope, long) |
long* / int64_t* (always 64-bit) |
Pointer.of(scope, float) |
float* |
Pointer.of(scope, double) |
double* |
Pointer.of(scope, byte) |
signed char* / 1-byte integer |
Pointer.of(scope, short) |
short* |
Pointer.of(scope, char) |
C char* (1 byte) |
Pointer.of(scope, boolean) |
C _Bool* (1 byte, 0/1) |
Pointer.of(scope, CString) |
C char** |
Pointer.of(scope, WString) |
C wchar_t** |
CString and WString already represent char* and wchar_t*. Wrap them in a
Pointer only when a native API expects a pointer to that address (char** or
wchar_t**):
CString text = scope.string("hello");
Pointer<CString> outText = Pointer.of(scope, text); // char**Memory is owned by scope and freed when the scope closes. There is no Pointer.of(10) without a scope — a pointer always needs an owner for native storage.
These layouts match the global type mappers (DefaultTypeMapper / NativeType). See NativeTypes.md for the full C type table.