Overview
Primitive Args
int, double, char, etc. are passed by value via registers or stack — no allocation involved.
String Args
When a parameter type isFFIType.CString, the NAPI bridge calls napi_get_value_string_utf8 to get the C string, allocates a char* on the heap, calls the C function, and immediately delete[] it. No user action needed.
String Return Values
callString returns a const char* owned by the C library. ArkFFI only reads its content via napi_create_string_utf8 — it does not allocate or free. The pointer lifecycle is managed by the C library.
Similarly, const char* fields from fromPtr return a pointer value pointing into C library memory. Do not pass it to releasePtr.
Struct Args
ArrayBuffer created by StructSchema.create() is allocated by the user. After passing it to a C function, the user owns its lifecycle.
Struct Returns (releasePtr)
When dlopen / CFunction has a StructSchema as returns, ArkFFI:
- Calls NAPI to obtain an
ArrayBuffer - Gets its data pointer via
ffi.ptr - Stores the
ArrayBufferin an internalMapto prevent GC - Returns the pointer to the user
fromPtr, call releasePtr to remove the Map reference and allow GC.
What if I forget to call releasePtr?
The internalMap holds the ArrayBuffer reference indefinitely. The pointer remains valid. The entry is only removed by releasePtr or program exit. This is generally harmless — entries grow linearly with struct return calls.
What if I pass the wrong pointer to releasePtr?
releasePtr(ptr) does a Map lookup by key. If ptr was not allocated by an ArkFFI struct return (e.g., a C library const char*), the key is not found and the call is silently ignored — no crash.
Pointer Types (ptr, callback)
FFIType.ptr and FFIType.callback pass address values (number) — no allocation. The address is managed by the C library or by JSCallback’s internal slot system.
Core Principle
ArkFFI only manages memory it allocates. C library memory is managed by the C library.