<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p>Note that if you just want to dispose of the string after the
      conversion, you can also do:<br>
      <br>
          private static String readUtf8String(MemorySegment segment) {<br>
              final MemorySegment string =
      segment.reinterpret(Long.MAX_VALUE);<br>
              String result = string.getUtf8String(0);<br>
              NativeMethods.disposeString(segment);<br>
              return result;<br>
          }</p>
    <p>This behaves more or less equivalently to your version. There's
      no need to create a new Arena. MemorySegment::reinterpret doesn't
      copy the underlying data, but MemorySegment::getUtf8String does.<br>
    </p>
    <p>Jorn<br>
    </p>
    <div class="moz-cite-prefix">On 30/09/2023 05:18, tison wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CALL9TYJkRzOCtwYk6O=euU_8NTNPwMbniebWO=5L-xZyQ_Q+uA@mail.gmail.com">
      
      <div dir="ltr">
        <div class="gmail_default" style="font-family:arial,sans-serif">Thank
          you! Finally I work out a string conversion utility:</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 String readUtf8String(MemorySegment segment)
          {<br>
                  try (Arena arena = Arena.ofConfined()) {<br>
                      final MemorySegment string =
          segment.reinterpret(Long.MAX_VALUE, arena,
          NativeMethods::disposeString);<br>
                      return string.getUtf8String(0);<br>
                  }<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">#[no_mangle]<br>
          pub unsafe extern "C" fn dispose_string(s: *mut c_char) {<br>
              drop(CString::from_raw(s))<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">Hopefully,
          this doesn't create too much overhead (I'm not sure the
          overhead of creating Arena), and no other leaks. It likes
          JNIEnv#NewString and IIUC JNIEnv#NewString also copy bytes.</div>
        <div class="gmail_default" style="font-family:arial,sans-serif"><br>
        </div>
        <div class="gmail_default" style="font-family:arial,sans-serif">> <span style="font-family:Arial,Helvetica,sans-serif">Native
            functions can just return NULL/0, and the linker will
            automatically translate that into MemorySegment.NULL.</span></div>
        <div class="gmail_default" style="font-family:arial,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif"><br>
          </span></div>
        <div class="gmail_default" style="font-family:arial,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif">Good to know!</span></div>
        <div class="gmail_default" style="font-family:arial,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif"><br>
          </span></div>
        <div class="gmail_default" style="font-family:arial,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif">> </span><span style="font-family:Arial,Helvetica,sans-serif">So, there is
            no FFM-specific API for the native code to interact with the
            Java side</span></div>
        <div class="gmail_default" style="font-family:arial,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif"><br>
          </span></div>
        <div class="gmail_default" style="font-family:arial,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif">OK. Perhaps I
            should return an error union in this case and decode &
            throw exceptions on the Java side.</span></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">Jorn Vernee <<a href="mailto:jorn.vernee@oracle.com" moz-do-not-send="true" class="moz-txt-link-freetext">jorn.vernee@oracle.com</a>>
          äºŽ2023å¹´9月29日周五 23:42写道:<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>
            <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">>
              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 class="gmail_default" style="font-family:arial,sans-serif">Native functions can
              just return NULL/0, and the linker will automatically
              translate that into MemorySegment.NULL.</div>
            <div class="gmail_default" style="font-family:arial,sans-serif"><br>
            </div>
            <div class="gmail_default" style="font-family:arial,sans-serif">As for throwing a
              Java exception from native code, similar to what is
              possible with JNI Throw(New) [1], this is not supported.
              The Linker operates on the general assumption that the
              native code it is interacting with has no knowledge about
              Java at all. So, there is no FFM-specific API for the
              native code to interact with the Java side.<br>
            </div>
            <div class="gmail_default" style="font-family:arial,sans-serif"><br>
            </div>
            <div class="gmail_default" style="font-family:arial,sans-serif">Jorn</div>
            <div class="gmail_default" style="font-family:arial,sans-serif"><br>
            </div>
            <div class="gmail_default" style="font-family:arial,sans-serif">[1]:
              <a href="https://docs.oracle.com/en/java/javase/21/docs/specs/jni/functions.html#throw" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">https://docs.oracle.com/en/java/javase/21/docs/specs/jni/functions.html#throw</a><br>
            </div>
            <div>On 29/09/2023 16:08, tison wrote:<br>
            </div>
            <blockquote type="cite">
              <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>
      </div>
    </blockquote>
  </body>
</html>