<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 28/05/2023 20:50, Clayton Walker
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CAEwKcDK-CbRUSjixyg=+9JF4i-8nHhq80YdonYZ2-ggcyKRP_Q@mail.gmail.com">
      
      <div dir="ltr">
        <div>I've had success calling jni and awt functions via panama
          and jextract-generated bindings. A few notes and questions
          below.<br>
        </div>
        <div><br>
        </div>
        <div>First off I noticed a bug in jextract, it appears that in
          an anonymous union the location will be dumped into the name
          field, which is invalid on windows. The backslashes need to be
          escaped.</div>
        <div>.withName("union (anonymous at
          C:\Users\Clayton\.jdks\openjdk-20.0.1\include\win32\jawt_md.h:42:5)"),</div>
        <div>I came across this when generating bindings to jawt on
          windows. Not sure if it makes sense to include that path or
          not but I was able to get around it by adding a Utils.quote
          call to Constants.java#340, like so append(".withName(\"" +
          Utils.quote(<a href="https://urldefense.com/v3/__http://l.name__;!!ACWV5N9M2RV99hQ!NZzKVdwoqGo5oDo6E4dLPZ7wZ5GFmFyiaSyGJk4cnIuOIOLfZ5PJL3wOxRylvOSOK-dvRUbJ2aHvsD1hLpnVPww8NZZmWkOH4w$" moz-do-not-send="true">l.name</a>().get()) + "\")");</div>
      </div>
    </blockquote>
    That seems indeeed a bug - thanks<br>
    <blockquote type="cite" cite="mid:CAEwKcDK-CbRUSjixyg=+9JF4i-8nHhq80YdonYZ2-ggcyKRP_Q@mail.gmail.com">
      <div dir="ltr">
        <div><br>
        </div>
        <div>Secondly, when using jextract does it make sense to call
          jextract once? For example, there are jni functions that come
          from jni.dll, but there are also awt functions that come from
          jawt.dll. Some of these functions share definitions. Certain
          functions need jni loaded, and certain ones need jawt. It
          doesn't necessarily make sense to load jawt if only jni
          functions are going to be called, but in my case it's fine. Is
          it expected for developers to call jextract twice, once per
          library, or to perhaps create a meta-header that references
          both?</div>
      </div>
    </blockquote>
    <p>I think creating the meta-header which includes both and passing
      that to jextract is a fine approach here. Note that you can also
      use the options for printing all symbols and then filtering them,
      as explained here:</p>
    <p><a class="moz-txt-link-freetext" href="https://github.com/openjdk/jextract#filtering-symbols">https://github.com/openjdk/jextract#filtering-symbols</a><br>
    </p>
    <blockquote type="cite" cite="mid:CAEwKcDK-CbRUSjixyg=+9JF4i-8nHhq80YdonYZ2-ggcyKRP_Q@mail.gmail.com">
      <div dir="ltr">
        <div><br>
        </div>
        <div>Also related to the above question, there are
          platform-specific headers, jni_md.h and jawt_md.h that differ
          depending on the platform. How are developers encouraged to
          share code in this place? Generate all platform definitions at
          once, or once per platform then merge the definitions, or once
          per platform and keep their jextract-extracted source
          separate?</div>
      </div>
    </blockquote>
    <p>I think the last option you mention is the most frequent I've
      seen used. Jextract itself does something different when
      interacting with libclang, as libclang is written in portable C
      (so e.g. uses "long long" instead of "long") and all layouts ends
      up being ok across platforms, so that we don't really need
      different versions. My feeling is that jni itself should be
      portable (after all, JNI types are modelled after _Java_ types,
      whose sizes are known), I don't know about jawt. But it is
      possible that the differences are related to functions you don't
      care about? (in which case, extracting a mininum common
      denominator wouldn't be too bad?)</p>
    <p>Maurizio<br>
    </p>
    <blockquote type="cite" cite="mid:CAEwKcDK-CbRUSjixyg=+9JF4i-8nHhq80YdonYZ2-ggcyKRP_Q@mail.gmail.com">
      <div dir="ltr">
        <div><br>
        </div>
      </div>
      <br>
      <div class="gmail_quote">
        <div dir="ltr" class="gmail_attr">On Wed, May 24, 2023 at
          3:08 PM Maurizio Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com" moz-do-not-send="true" class="moz-txt-link-freetext">maurizio.cimadamore@oracle.com</a>>
          wrote:<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>
            <p><br>
            </p>
            <div>On 24/05/2023 20:36, Clayton Walker wrote:<br>
            </div>
            <blockquote type="cite">
              <div dir="ltr">Hi Maurizio,
                <div>thanks for the detailed response!</div>
                <div><br>
                </div>
                <div>I believe I understood this for the most part, but
                  a quick question related to the jni references. Do we
                  need to use NewGlobalRef so that we can exit the
                  native jni function and not have their jni reference
                  freed?</div>
              </div>
            </blockquote>
            Yes, the global ref is required given that we go in and out
            of JNI functions. Are you worried about the cost of creating
            global references? (Trying to understand more about the use
            case)<br>
            <blockquote type="cite">
              <div dir="ltr">
                <div><br>
                </div>
                <div>Also would it make more sense to go this route than
                  to expose a new function called (e.g.)
                  getDrawingSurface method to the awt Component class
                  which returns a MemorySegment that we can free?
                  Presumably to avoid cluttering up awt/swing with
                  additional native function calls, or perhaps avoid
                  leaking implementation details to the java standard
                  library?</div>
              </div>
            </blockquote>
            <p>I'm not an expert in AWT/Swing - but it would seem that,
              at a glance, the Component class doesn't have much in
              terms of low-level capabilities. So exposing a method
              which returns a segment (or a ByteBuffer) would look a bit
              odd, I think.</p>
            <p>Cheers<br>
              Maurizio<br>
            </p>
            <blockquote type="cite"><br>
              <div class="gmail_quote">
                <div dir="ltr" class="gmail_attr">On Wed, May 24, 2023
                  at 12:22 PM Maurizio Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">maurizio.cimadamore@oracle.com</a>>
                  wrote:<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>
                    <p>Hi Clayton<br>
                      interacting with JNI code has few issues:<br>
                      <br>
                      1. you need a JNIEnv* segment<br>
                      2. you need to be able to wrap Java objects as JNI
                      references (so that they can be passed as pointers
                      to native calls)<br>
                      3. expose some way to map method names into JNI
                      mangled names (so that we can look those up using
                      a symbol lookup)<br>
                    </p>
                    <p>This is something on our radar and we will like
                      to address this use case at some point (but it is
                      possible this might be addressed _after_ the FFM
                      API is finalized). Two possible approaches are:</p>
                    <p>* a set of static helper functions which allow to
                      obtain JNIEnv segment, as well as create,
                      dereference and destroy JNI refs. We might even
                      expose JNI functions here (think of a JNIUtils
                      class)<br>
                      * a true JNILinker <: Linker - this might allow
                      a tighter coupling with JNI functions (as the
                      JNIEnv will be passed automatically)<br>
                    </p>
                    <p>I think the former approach is quite attractive
                      in terms of bang for bucks. It doesn't add a lot
                      of complexity to the API, and adds the minimum
                      functionality that is required in order to allow
                      the native linker to deal with JNI functions as
                      well (even though developers will need to take
                      some extra care when doing so).</p>
                    <p>In the meantime, I think it might be possible to
                      define a small JNI library which takes care of the
                      missing functionalities - e.g. it could
                      return/accept JNI references as "jlong" (an hack,
                      I know) so, something like this:<br>
                    </p>
                    <p>native long makeGlobalRef(Object o) // call
                      NewGlobalRef, cast result to jlong and return<br>
                      native void destroyGlobalRef(long ref) // cast to
                      jobject, then call DeleteGlobalRef<br>
                      native Object readGlobalRef(long ref) // cast to
                      jobject, return<br>
                      native long getEnv(); // cast env parameter to
                      jlong and return<br>
                    </p>
                    <p>I've tried something along those lines and it
                      seems to work as expected. But I agree that it
                      would be convenient if this "just worked" out of
                      the box.</p>
                    <p>Cheers<br>
                      Maurizio<br>
                    </p>
                    <p><br>
                    </p>
                    <p><br>
                    </p>
                    <div>On 24/05/2023 18:28, Clayton Walker wrote:<br>
                    </div>
                    <blockquote type="cite">
                      <div dir="ltr">I am working on a project with one
                        of the goals being able to use a swing component
                        as a render target. From the documentation <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/awt/AWT_Native_Interface.html" target="_blank" moz-do-not-send="true">here</a> I
                        assume we need jni in order to access the native
                        PlatformInfo struct. My question is the same as
                        asked in <a href="https://urldefense.com/v3/__https://stackoverflow.com/questions/75620948/how-do-i-get-the-hwnd-of-a-canvas-using-panama__;!!ACWV5N9M2RV99hQ!Pq0tFxFIxoDHgX_vezwj24Kuk4wsYvPXLMS09T7SYv_UyIpO7nN_Sc1jmNWMzwSORL6P3_hbxJIXfK4h2FNcd_LAkn4CRaOc8w$" target="_blank" moz-do-not-send="true">this
                          stackoverflow question</a>, is it possible to
                        use panama to get the HWND of a swing window?</div>
                    </blockquote>
                  </div>
                </blockquote>
              </div>
            </blockquote>
          </div>
        </blockquote>
      </div>
    </blockquote>
  </body>
</html>