// CPD-OFF — FFI opaque-handle return, no JSON deserialization needed.
// The returned pointer is owned by the new wrapper, which frees it in
// close(); freeing it here would leave the wrapper holding a dangling
// handle (use-after-free on the next native call).
MemorySegment resultPtr = (MemorySegment) {{ ffi_handle }}.invoke({{ args_joined }});
{{ named_frees }} if (resultPtr.equals(MemorySegment.NULL)) {
checkLastFfiError();
return {{ empty_return }};
}
return {{ success_return }};
// CPD-ON