<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <div class="moz-cite-prefix">Hi,<br>
      <br>
      The interop support for C++ is currently work in progress, some
      things work already, others not yet.<br>
      Some of the C++ interop features are behind a flag, try passing
      &quot;--llvm.C++Interop&quot;.<br>
    </div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix">Calling constructors and non-virtual
      methods should work already.<br>
    </div>
    <div class="moz-cite-prefix">There is a WIP PR for virtual method
      calls: <a class="moz-txt-link-freetext" href="https://github.com/oracle/graal/pull/2932">https://github.com/oracle/graal/pull/2932</a></div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix">C++ interop is a very recent feature
      and doesn't have many users yet, so there might be bugs.<br>
    </div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix">Some more comments inline below...<br>
    </div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix">On 1/25/21 10:48 PM, Darrell Schiebel
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CAPgAq0mR6FwCdRcZgmZ8dU9pbXJKc2JUFSoKZtgfU61GZKHa_w@mail.gmail.com">
      
      <div dir="ltr">
        <div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small">Hello,</div>
        <div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small"><br>
        </div>
        <div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small">I'm
          trying to understand the capabilities and limitations of using
          C++ libraries from Java. One of the more complete examples I
          could find was the:</div>
        <div class="gmail_default">
          <ul>
            <li>
              <p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span style="font-variant-ligatures:no-common-ligatures">CxxMethodsTest.java/</span><span style="font-variant-ligatures:no-common-ligatures">methodsTest.cpp</span></p>
            </li>
          </ul>
          <div><font face="verdana, sans-serif">test from the GraalVM
              distribution. I removed the unit test framework, but I
              find that there are some operations which fail (in Java):</font></div>
          <div>
            <ol>
              <li><font face="verdana, sans-serif">retrieving a class:&nbsp;</font>testLibrary.getMember(&quot;Point&quot;)</li>
            </ol>
          </div>
        </div>
      </div>
    </blockquote>
    <p>That should already work. You should be able to use to create
      instances of &quot;Point&quot; (with `point.newInstance(...)`).<br>
      It might be that this needs the &quot;--llvm.C++Interop&quot; flag though.<br>
      <br>
    </p>
    <blockquote type="cite" cite="mid:CAPgAq0mR6FwCdRcZgmZ8dU9pbXJKc2JUFSoKZtgfU61GZKHa_w@mail.gmail.com">
      <div dir="ltr">
        <div class="gmail_default">
          <div>
            <ol>
              <li><font face="verdana, sans-serif">retrieving a class
                  method:&nbsp;</font>squaredEuclideanDistance =
                testLibrary.getMember(&quot;squaredEuclideanDistance&quot;)</li>
            </ol>
          </div>
        </div>
      </div>
    </blockquote>
    That doesn't work since &quot;squaredEuclideanDistance&quot; is not a global
    function. If you have an instance of &quot;Point&quot;, you should be able to
    `point.getMember(&quot;squaredEuclideanDistance&quot;)` and execute the
    result, or just use `point.invokeMember(&quot;squaredEuclideanDistance&quot;,
    ...)` to directly invoke methods.<br>
    <br>
    <blockquote type="cite" cite="mid:CAPgAq0mR6FwCdRcZgmZ8dU9pbXJKc2JUFSoKZtgfU61GZKHa_w@mail.gmail.com">
      <div dir="ltr">
        <div class="gmail_default">
          <div>
            <ol>
              <li><font face="verdana, sans-serif">invoking a class
                  member:&nbsp;</font>testLibrary.invokeMember(&quot;setY&quot;,
                point2, 8)</li>
            </ol>
          </div>
        </div>
      </div>
    </blockquote>
    Same thing. This needs to be `point2.invokeMember(&quot;setY&quot;, 8)`.<br>
    <br>
    <blockquote type="cite" cite="mid:CAPgAq0mR6FwCdRcZgmZ8dU9pbXJKc2JUFSoKZtgfU61GZKHa_w@mail.gmail.com">
      <div dir="ltr">
        <div class="gmail_default">
          <div>
            <div><font face="verdana, sans-serif">I am using GraalVM
                21.0.0, and I compiled the C++ like:</font></div>
            <div>
              <ul>
                <li>
                  <p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span style="font-variant-ligatures:no-common-ligatures">clang++
                      -std=c++11 -shared -o methodsTest.so
                      methodsTest.cpp -lgraalvm-llvm</span></p>
                </li>
              </ul>
              <div><font face="verdana, sans-serif">I suppose maybe the
                  testing framework may compile the C++ source code
                  differently. Any idea where I've gone astray?</font></div>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
    <p><font face="verdana, sans-serif">Is that &quot;clang++&quot; from the
        toolchain we ship with GraalVM? If yes, then that's the correct
        way to build.<br>
        <br>
        If no: If you want to use interop (both C++ or C), you need to
        compile with debug info enabled. Also note that we currently
        only support libc++ (the one from the LLVM project), not
        libstdc++ (the one from GCC, which is the default on most Linux
        systems).</font></p>
    <p><font face="verdana, sans-serif"><font face="verdana, sans-serif">You
          can get the path to our toolchain using &quot;lli
          --print-toolchain-path&quot; (you might have to install it using
          &quot;gu install llvm-toolchain&quot;, it's an optional component since
          you don't need it at runtime). </font>The &quot;clang++&quot; from
        there automatically sets the correct flags. You can use &quot;-v&quot; to
        see what exactly it does.</font><font face="verdana, sans-serif"><br>
      </font></p>
    <font face="verdana, sans-serif"><br>
    </font><br>
    <blockquote type="cite" cite="mid:CAPgAq0mR6FwCdRcZgmZ8dU9pbXJKc2JUFSoKZtgfU61GZKHa_w@mail.gmail.com">
      <div dir="ltr">
        <div class="gmail_default">
          <div>
            <div>
              <div><font face="verdana, sans-serif">I think they may
                  compile without name mangling or perhaps they compile
                  the cpp file on the fly... I don't know exactly what
                  happens&nbsp;behind the scenes with:</font></div>
              <div>
                <ul>
                  <li>
                    <p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures">testLibrary
                        = loadTestBitcodeValue(&quot;methodsTest.cpp&quot;)</span></p>
                  </li>
                </ul>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
    That's just some path manipulation to locate .so file for that test,
    which is somewhere under mxbuild in a directory called
    &quot;methodsTest.cpp.dir&quot;. It doesn't do any compilation, that is done
    using mx and make.<br>
    <br>
    <blockquote type="cite" cite="mid:CAPgAq0mR6FwCdRcZgmZ8dU9pbXJKc2JUFSoKZtgfU61GZKHa_w@mail.gmail.com">
      <div dir="ltr">
        <div class="gmail_default">
          <div>
            <div>
              <div>
                <div><font face="verdana, sans-serif">My
                    modified&nbsp;methodsTest.cpp file is down below.</font></div>
                <div><font face="verdana, sans-serif"><br>
                  </font></div>
                <div><span style="font-family:verdana,sans-serif">It
                    seems like these are the key points:</span><br>
                </div>
              </div>
              <div>
                <ul>
                  <li><font face="verdana, sans-serif">pointers should
                      be used to pass/return objects (no mapping from
                      List&lt;T&gt; to std::list&lt;T&gt; for example)</font></li>
                </ul>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
    <font face="verdana, sans-serif">Correct, currently we don't support
      by-value arguments in interop (except primitives of course).
      Everything must be pointers. Not sure about C++ references, they
      should work in principle, since in bitcode they are also just
      pointers. But I've never tried to be honest.<br>
    </font><br>
    <blockquote type="cite" cite="mid:CAPgAq0mR6FwCdRcZgmZ8dU9pbXJKc2JUFSoKZtgfU61GZKHa_w@mail.gmail.com">
      <div dir="ltr">
        <div class="gmail_default">
          <div>
            <div>
              <div>
                <ul>
                  <li><font face="verdana, sans-serif">mangled names do
                      not work (unless the mangled name is used for
                      lookup, of course)</font></li>
                </ul>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
    <font face="verdana, sans-serif">With the &quot;--llvm.C++Interop&quot; flag
      that should work. We read the unmangled names from the debug info.<br>
      This probably only works if there is no name conflict with the
      unmangled name, i.e. no overloading.<br>
    </font><br>
    <blockquote type="cite" cite="mid:CAPgAq0mR6FwCdRcZgmZ8dU9pbXJKc2JUFSoKZtgfU61GZKHa_w@mail.gmail.com">
      <div dir="ltr">
        <div class="gmail_default">
          <div>
            <div>
              <div>
                <ul>
                  <li><font face="verdana, sans-serif">class based
                      inherited methods work (using an object pointer)</font></li>
                  <li><font face="verdana, sans-serif">looking up
                      methods and supplying the object and args does not
                      work (e.g. squareEuclideanDistance above)</font></li>
                  <li><font face="verdana, sans-serif">retrieving object
                      constructor as a function (e.g. getMember(&quot;Point&quot;)
                      above)</font></li>
                </ul>
                <div><font face="verdana, sans-serif">Does this seem
                    right? I've looked at the examples I could find on
                    the GraalVM.org website but are there any bigger
                    examples of Java/C++ integration via GraalVM?</font></div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
    <font face="verdana, sans-serif">Since this is a work in progress
      feature, we don't have any published examples for C++ yet.<br>
      <br>
      Most of our users are only using C-based interfaces, even if the
      actual implementation behind the interface is in C++. That is of
      course a workaround you can use right now, but not a nice one.<br>
      We'll probably publish more examples once we reach a more complete
      state of our C++ interop implementation.<br>
      <br>
      <br>
      As I wrote in the beginning, all of this is pretty new, so not
      everything might work out of the box. You're welcome to play
      around with it, and if you get stuck, feel free to ask questions
      or report issues!<br>
      <br>
      <br>
      - Roland<br>
    </font><br>
    <blockquote type="cite" cite="mid:CAPgAq0mR6FwCdRcZgmZ8dU9pbXJKc2JUFSoKZtgfU61GZKHa_w@mail.gmail.com">
      <div dir="ltr">
        <div class="gmail_default">
          <div>
            <div>
              <div>
                <div><font face="verdana, sans-serif"><br>
                  </font></div>
                <div><font face="verdana, sans-serif">thanks for any
                    advice,</font></div>
                <div><font face="verdana, sans-serif">Darrell</font></div>
                <div><font face="verdana, sans-serif"><br>
                  </font></div>
                <div><font face="verdana, sans-serif">/*<br>
                    &nbsp;* Copyright (c) 2020, Oracle and/or its affiliates.<br>
                    &nbsp;*<br>
                    &nbsp;* All rights reserved.<br>
                    &nbsp;*<br>
                    &nbsp;* Redistribution and use in source and binary
                    forms, with or without modification, are<br>
                    &nbsp;* permitted provided that the following conditions
                    are met:<br>
                    &nbsp;*<br>
                    &nbsp;* 1. Redistributions of source code must retain the
                    above copyright notice, this list of<br>
                    &nbsp;* conditions and the following disclaimer.<br>
                    &nbsp;*<br>
                    &nbsp;* 2. Redistributions in binary form must reproduce
                    the above copyright notice, this list of<br>
                    &nbsp;* conditions and the following disclaimer in the
                    documentation and/or other materials provided<br>
                    &nbsp;* with the distribution.<br>
                    &nbsp;*<br>
                    &nbsp;* 3. Neither the name of the copyright holder nor
                    the names of its contributors may be used to<br>
                    &nbsp;* endorse or promote products derived from this
                    software without specific prior written<br>
                    &nbsp;* permission.<br>
                    &nbsp;*<br>
                    &nbsp;* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
                    HOLDERS AND CONTRIBUTORS &quot;AS IS&quot; AND ANY EXPRESS<br>
                    &nbsp;* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                    TO, THE IMPLIED WARRANTIES OF<br>
                    &nbsp;* MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                    PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE<br>
                    &nbsp;* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
                    ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,<br>
                    &nbsp;* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
                    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE<br>
                    &nbsp;* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
                    OR BUSINESS INTERRUPTION) HOWEVER CAUSED<br>
                    &nbsp;* AND ON ANY THEORY OF LIABILITY, WHETHER IN
                    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING<br>
                    &nbsp;* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
                    OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED<br>
                    &nbsp;* OF THE POSSIBILITY OF SUCH DAMAGE.<br>
                    &nbsp;*/<br>
                    #include &lt;graalvm/llvm/polyglot.h&gt;<br>
                    #include &lt;stdlib.h&gt;<br>
                    #include &lt;math.h&gt;<br>
                    <br>
                    #define EXTERN extern &quot;C&quot;<br>
                    <br>
                    class Point {<br>
                    protected:<br>
                    &nbsp; &nbsp; int x;<br>
                    &nbsp; &nbsp; int y;<br>
                    <br>
                    public:<br>
                    &nbsp; &nbsp; Point();<br>
                    &nbsp; &nbsp; int getX();<br>
                    &nbsp; &nbsp; int getY();<br>
                    &nbsp; &nbsp; void setX(int val);<br>
                    &nbsp; &nbsp; void setY(int val);<br>
                    &nbsp; &nbsp; double squaredEuclideanDistance(Point *other);<br>
                    };<br>
                    <br>
                    POLYGLOT_DECLARE_TYPE(Point)<br>
                    <br>
                    class XtendPoint : public Point {<br>
                    private:<br>
                    &nbsp; &nbsp; int z;<br>
                    <br>
                    public:<br>
                    &nbsp; &nbsp; XtendPoint();<br>
                    &nbsp; &nbsp; int getZ();<br>
                    &nbsp; &nbsp; void setZ(int val);<br>
                    &nbsp; &nbsp; int getZ(int constant);<br>
                    &nbsp; &nbsp; int getX();<br>
                    };<br>
                    <br>
                    POLYGLOT_DECLARE_TYPE(XtendPoint)<br>
                    <br>
                    //class methods<br>
                    <br>
                    Point::Point() {<br>
                    &nbsp; &nbsp; x = 0;<br>
                    &nbsp; &nbsp; y = 0;<br>
                    }<br>
                    <br>
                    int Point::getX() {<br>
                    &nbsp; &nbsp; return x;<br>
                    }<br>
                    <br>
                    int Point::getY() {<br>
                    &nbsp; &nbsp; return y;<br>
                    }<br>
                    <br>
                    void Point::setX(int val) {<br>
                    &nbsp; &nbsp; x = val;<br>
                    }<br>
                    <br>
                    void Point::setY(int val) {<br>
                    &nbsp; &nbsp; y = val;<br>
                    }<br>
                    <br>
                    double Point::squaredEuclideanDistance(Point *other)
                    {<br>
                    &nbsp; &nbsp; double dX = (double) (x - other-&gt;x);<br>
                    &nbsp; &nbsp; double dY = (double) (y - other-&gt;y);<br>
                    &nbsp; &nbsp; return dX * dX + dY * dY;<br>
                    }<br>
                    <br>
                    XtendPoint::XtendPoint() {<br>
                    &nbsp; &nbsp; z = 0;<br>
                    }<br>
                    <br>
                    int XtendPoint::getZ() {<br>
                    &nbsp; &nbsp; return z;<br>
                    }<br>
                    <br>
                    void XtendPoint::setZ(int dZ) {<br>
                    &nbsp; &nbsp; z = dZ;<br>
                    }<br>
                    <br>
                    int XtendPoint::getZ(int constantOffset) {<br>
                    &nbsp; &nbsp; return z + constantOffset;<br>
                    }<br>
                    <br>
                    int XtendPoint::getX() {<br>
                    &nbsp; &nbsp; return x * 2;<br>
                    }<br>
                    <br>
                    //functions<br>
                    EXTERN void *allocNativePoint() {<br>
                    &nbsp; &nbsp; Point *ret = (Point *) malloc(sizeof(*ret));<br>
                    &nbsp; &nbsp; return polyglot_from_Point(ret);<br>
                    }<br>
                    <br>
                    EXTERN void *allocNativeXtendPoint() {<br>
                    &nbsp; &nbsp; XtendPoint *ret = (XtendPoint *)
                    malloc(sizeof(*ret));<br>
                    &nbsp; &nbsp; return polyglot_from_XtendPoint(ret);<br>
                    }<br>
                    <br>
                    EXTERN void swap(Point *p, Point *q) {<br>
                    &nbsp; &nbsp; Point tmp = *q;<br>
                    &nbsp; &nbsp; *q = *p;<br>
                    &nbsp; &nbsp; *p = tmp;<br>
                    }<br>
                    <br>
                    EXTERN void freeNativePoint(Point *p) {<br>
                    &nbsp; &nbsp; free(p);<br>
                    }<br>
                    <br>
                    EXTERN void freeNativeXtendPoint(XtendPoint *p) {<br>
                    &nbsp; &nbsp; free(p);<br>
                    }<br>
                  </font></div>
                <div><font face="verdana, sans-serif"><br>
                  </font></div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <pre class="moz-quote-pre" wrap="">_______________________________________________
GraalVM-Users mailing list
<a class="moz-txt-link-abbreviated" href="mailto:GraalVM-Users@oss.oracle.com">GraalVM-Users@oss.oracle.com</a>
<a class="moz-txt-link-freetext" href="https://oss.oracle.com/mailman/listinfo/graalvm-users">https://oss.oracle.com/mailman/listinfo/graalvm-users</a></pre>
    </blockquote>
    <p><br>
    </p>
  </body>
</html>