<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p>Yes, if native code is allocating stuff, the way to go is to use
reinterpret. This is covered here:</p>
<p><a class="moz-txt-link-freetext" href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/foreign/Linker.html#by-ref">https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/foreign/Linker.html#by-ref</a><br>
</p>
<p>And, in more details, here</p>
<p><a class="moz-txt-link-freetext" href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/foreign/MemorySegment.html#wrapping-addresses">https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/foreign/MemorySegment.html#wrapping-addresses</a></p>
<p>If you don't want to resize all your segments explicitly and work
in "sudo" mode, an escape hatch is also possible: create an
address layout whose target layout has maximal size:</p>
<p>```<br>
static final AddressLayout ADDRESS_UNBOUNDED =
ValueLayout.ADDRESS.withTargetLayout(MemoryLayout.sequenceLayout(Long.MAX_VALUE,
ValueLayout.JAVA_BYTE));<br>
```</p>
<p>And then use `ADDRESS_UNBOUNDED` everywhere. Now all the segments
wrapping pointers returned by native code will have maximal size,
and no OOBE will be issued.</p>
<p>Which approach you take, and how much safety you want to enforce,
is up to you. The API presents you with a choice and a range of
options here.</p>
<p>Cheers<br>
Maurizio<br>
</p>
<p><br>
</p>
<div class="moz-cite-prefix">On 29/09/2023 15:23, tison wrote:<br>
</div>
<blockquote type="cite" cite="mid:CALL9TYJUuxGq1KXqgpvpfowAmyxU_W9sT7KLH4aDQ6WjAPtdMA@mail.gmail.com">
<div dir="ltr">
<div class="gmail_default" style="font-family:arial,sans-serif">I
found reinterpret that can help in the first step where
length=0 for the returned memory. So we may return a leading
long with how many bytes is followed?</div>
<div class="gmail_default" style="font-family:arial,sans-serif"><br>
</div>
<div class="gmail_default" style="font-family:arial,sans-serif">final
MemorySegment version = (MemorySegment)
datafusionVersionMethodHandle.invokeExact();<br>
return version.reinterpret(10, arena).getUtf8String(0);<br>
</div>
<div class="gmail_default" style="font-family:arial,sans-serif"><br>
</div>
<div>
<div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">
<div dir="ltr">
<div>
<div dir="ltr">
<div>
<div dir="ltr">
<div>
<div dir="ltr">
<div><font face="arial, sans-serif">Best,</font></div>
<div><font face="arial, sans-serif">tison.</font></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<br>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">tison <<a href="mailto:wander4096@gmail.com" moz-do-not-send="true" class="moz-txt-link-freetext">wander4096@gmail.com</a>>
于2023年9月29日周五 22:08写道:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir="ltr">
<div class="gmail_default" style="font-family:arial,sans-serif">Here is my native
method written in Rust:</div>
<div class="gmail_default" style="font-family:arial,sans-serif"><br>
</div>
<div class="gmail_default" style="font-family:arial,sans-serif">#[no_mangle]<br>
pub unsafe extern "C" fn datafusion_version() -> *const
c_char {<br>
CString::new(datafusion::DATAFUSION_VERSION).unwrap().into_raw()<br>
}<br>
</div>
<div class="gmail_default" style="font-family:arial,sans-serif"><br>
</div>
<div class="gmail_default" style="font-family:arial,sans-serif">And below is my
attempt to bind it with FFM APIs:</div>
<div class="gmail_default" style="font-family:arial,sans-serif"><br>
</div>
<div class="gmail_default" style="font-family:arial,sans-serif"> static
MethodHandle createMethodHandle(String name,
FunctionDescriptor descriptor) {<br>
final MemorySegment fp =
LOADER.lookup.find(name).orElseThrow();<br>
return LOADER.linker.downcallHandle(fp,
descriptor);<br>
}<br>
</div>
<div class="gmail_default" style="font-family:arial,sans-serif"><br>
</div>
<div class="gmail_default" style="font-family:arial,sans-serif"> private static
final MethodHandle datafusionVersionMethodHandle =
NativeLoader.createMethodHandle(datafusionVersionMethodName,
datafusionVersionMethodDesc);<br>
<br>
@SneakyThrows<br>
public static String datafusionVersion() {<br>
final MemorySegment version = (MemorySegment)
datafusionVersionMethodHandle.invokeExact();<br>
return version.getUtf8String(0);<br>
}<br>
</div>
<div class="gmail_default" style="font-family:arial,sans-serif"><br>
</div>
<div class="gmail_default" style="font-family:arial,sans-serif">I noticed that the
returned MemorySegment is always with length 0 and thus
any access with return OutOfBoundException.</div>
<div class="gmail_default" style="font-family:arial,sans-serif"><br>
</div>
<div class="gmail_default" style="font-family:arial,sans-serif">In the demos from
JEP, all memory segments are allocated from the Java side
and the native code only move or modify those allocated
memory segments instead of allocate/shrink memory.</div>
<div class="gmail_default" style="font-family:arial,sans-serif"><br>
</div>
<div class="gmail_default" style="font-family:arial,sans-serif">I wonder what is the
formal method to allocate a string from native methods and
pass back to the Java world.</div>
<div class="gmail_default" style="font-family:arial,sans-serif"><br>
</div>
<div class="gmail_default" style="font-family:arial,sans-serif">And, if we think of
error handling, how do we properly return a NULL from
native methods, and how do we throw exceptions from native
methods?</div>
<div class="gmail_default" style="font-family:arial,sans-serif"><br>
</div>
<div class="gmail_default" style="font-family:arial,sans-serif">MemorySegment.NULL
seems an Object without overriding equals, and JNIEnv's
throw counterpart is missing or I don't find it (perhaps
upcall helps but it's still a bit away from real-world
usage).</div>
<div class="gmail_default" style="font-family:arial,sans-serif"><br>
</div>
<div>
<div dir="ltr" class="gmail_signature">
<div dir="ltr">
<div>
<div dir="ltr">
<div>
<div dir="ltr">
<div>
<div dir="ltr">
<div><font face="arial, sans-serif">Best,</font></div>
<div><font face="arial, sans-serif">tison.</font></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</blockquote>
</body>
</html>