            var outPtrHolder = arena.allocate(ValueLayout.ADDRESS);
            var outLenHolder = arena.allocate(ValueLayout.JAVA_LONG);
            var outCapHolder = arena.allocate(ValueLayout.JAVA_LONG);
            int rc = (int) (long) {{ ffi_handle }}.invoke({{ args }}outPtrHolder, outLenHolder, outCapHolder);
            if (rc != 0) {
                checkLastError();
{%- if optional %}
                return Optional.empty();
{%- else %}
                return null;
{%- endif %}
            }
            var outPtr = outPtrHolder.get(ValueLayout.ADDRESS, 0);
            long outLen = outLenHolder.get(ValueLayout.JAVA_LONG, 0);
            long outCap = outCapHolder.get(ValueLayout.JAVA_LONG, 0);
            if (outPtr.equals(MemorySegment.NULL)) {
                checkLastError();
{%- if optional %}
                return Optional.empty();
{%- else %}
                return null;
{%- endif %}
            }
            byte[] result = outPtr.reinterpret(outLen).toArray(ValueLayout.JAVA_BYTE);
            {{ free_bytes_handle }}.invoke(outPtr, outLen, outCap);
{%- if optional %}
            return Optional.of(result);
{%- else %}
            return result;
{%- endif %}
