<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
"--llvm.C++Interop".<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: </font>testLibrary.getMember("Point")</li>
</ol>
</div>
</div>
</div>
</blockquote>
<p>That should already work. You should be able to use to create
instances of "Point" (with `point.newInstance(...)`).<br>
It might be that this needs the "--llvm.C++Interop" 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: </font>squaredEuclideanDistance =
testLibrary.getMember("squaredEuclideanDistance")</li>
</ol>
</div>
</div>
</div>
</blockquote>
That doesn't work since "squaredEuclideanDistance" is not a global
function. If you have an instance of "Point", you should be able to
`point.getMember("squaredEuclideanDistance")` and execute the
result, or just use `point.invokeMember("squaredEuclideanDistance",
...)` 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: </font>testLibrary.invokeMember("setY",
point2, 8)</li>
</ol>
</div>
</div>
</div>
</blockquote>
Same thing. This needs to be `point2.invokeMember("setY", 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 "clang++" 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 "lli
--print-toolchain-path" (you might have to install it using
"gu install llvm-toolchain", it's an optional component since
you don't need it at runtime). </font>The "clang++" from
there automatically sets the correct flags. You can use "-v" 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 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("methodsTest.cpp")</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
"methodsTest.cpp.dir". 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 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<T> to std::list<T> 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 "--llvm.C++Interop" 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("Point")
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>
* Copyright (c) 2020, Oracle and/or its affiliates.<br>
*<br>
* All rights reserved.<br>
*<br>
* Redistribution and use in source and binary
forms, with or without modification, are<br>
* permitted provided that the following conditions
are met:<br>
*<br>
* 1. Redistributions of source code must retain the
above copyright notice, this list of<br>
* conditions and the following disclaimer.<br>
*<br>
* 2. Redistributions in binary form must reproduce
the above copyright notice, this list of<br>
* conditions and the following disclaimer in the
documentation and/or other materials provided<br>
* with the distribution.<br>
*<br>
* 3. Neither the name of the copyright holder nor
the names of its contributors may be used to<br>
* endorse or promote products derived from this
software without specific prior written<br>
* permission.<br>
*<br>
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS<br>
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF<br>
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE<br>
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,<br>
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE<br>
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED<br>
* AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING<br>
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED<br>
* OF THE POSSIBILITY OF SUCH DAMAGE.<br>
*/<br>
#include <graalvm/llvm/polyglot.h><br>
#include <stdlib.h><br>
#include <math.h><br>
<br>
#define EXTERN extern "C"<br>
<br>
class Point {<br>
protected:<br>
int x;<br>
int y;<br>
<br>
public:<br>
Point();<br>
int getX();<br>
int getY();<br>
void setX(int val);<br>
void setY(int val);<br>
double squaredEuclideanDistance(Point *other);<br>
};<br>
<br>
POLYGLOT_DECLARE_TYPE(Point)<br>
<br>
class XtendPoint : public Point {<br>
private:<br>
int z;<br>
<br>
public:<br>
XtendPoint();<br>
int getZ();<br>
void setZ(int val);<br>
int getZ(int constant);<br>
int getX();<br>
};<br>
<br>
POLYGLOT_DECLARE_TYPE(XtendPoint)<br>
<br>
//class methods<br>
<br>
Point::Point() {<br>
x = 0;<br>
y = 0;<br>
}<br>
<br>
int Point::getX() {<br>
return x;<br>
}<br>
<br>
int Point::getY() {<br>
return y;<br>
}<br>
<br>
void Point::setX(int val) {<br>
x = val;<br>
}<br>
<br>
void Point::setY(int val) {<br>
y = val;<br>
}<br>
<br>
double Point::squaredEuclideanDistance(Point *other)
{<br>
double dX = (double) (x - other->x);<br>
double dY = (double) (y - other->y);<br>
return dX * dX + dY * dY;<br>
}<br>
<br>
XtendPoint::XtendPoint() {<br>
z = 0;<br>
}<br>
<br>
int XtendPoint::getZ() {<br>
return z;<br>
}<br>
<br>
void XtendPoint::setZ(int dZ) {<br>
z = dZ;<br>
}<br>
<br>
int XtendPoint::getZ(int constantOffset) {<br>
return z + constantOffset;<br>
}<br>
<br>
int XtendPoint::getX() {<br>
return x * 2;<br>
}<br>
<br>
//functions<br>
EXTERN void *allocNativePoint() {<br>
Point *ret = (Point *) malloc(sizeof(*ret));<br>
return polyglot_from_Point(ret);<br>
}<br>
<br>
EXTERN void *allocNativeXtendPoint() {<br>
XtendPoint *ret = (XtendPoint *)
malloc(sizeof(*ret));<br>
return polyglot_from_XtendPoint(ret);<br>
}<br>
<br>
EXTERN void swap(Point *p, Point *q) {<br>
Point tmp = *q;<br>
*q = *p;<br>
*p = tmp;<br>
}<br>
<br>
EXTERN void freeNativePoint(Point *p) {<br>
free(p);<br>
}<br>
<br>
EXTERN void freeNativeXtendPoint(XtendPoint *p) {<br>
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>