<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>