[graalvm-users] c++ bytecode from java
Darrell Schiebel
darrell at schiebel.us
Mon Jan 25 13:48:57 PST 2021
Hello,
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:
-
CxxMethodsTest.java/methodsTest.cpp
test from the GraalVM distribution. I removed the unit test framework, but
I find that there are some operations which fail (in Java):
1. retrieving a class: testLibrary.getMember("Point")
2. retrieving a class method: squaredEuclideanDistance =
testLibrary.getMember("squaredEuclideanDistance")
3. invoking a class member: testLibrary.invokeMember("setY", point2, 8)
I am using GraalVM 21.0.0, and I compiled the C++ like:
-
clang++ -std=c++11 -shared -o methodsTest.so methodsTest.cpp
-lgraalvm-llvm
I suppose maybe the testing framework may compile the C++ source code
differently. Any idea where I've gone astray? 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:
-
testLibrary = loadTestBitcodeValue("methodsTest.cpp")
My modified methodsTest.cpp file is down below.
It seems like these are the key points:
- pointers should be used to pass/return objects (no mapping from
List<T> to std::list<T> for example)
- mangled names do not work (unless the mangled name is used for lookup,
of course)
- class based inherited methods work (using an object pointer)
- looking up methods and supplying the object and args does not work
(e.g. squareEuclideanDistance above)
- retrieving object constructor as a function (e.g. getMember("Point")
above)
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?
thanks for any advice,
Darrell
/*
* Copyright (c) 2020, Oracle and/or its affiliates.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright
notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
notice, this list of
* conditions and the following disclaimer in the documentation and/or
other materials provided
* with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
contributors may be used to
* endorse or promote products derived from this software without specific
prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <graalvm/llvm/polyglot.h>
#include <stdlib.h>
#include <math.h>
#define EXTERN extern "C"
class Point {
protected:
int x;
int y;
public:
Point();
int getX();
int getY();
void setX(int val);
void setY(int val);
double squaredEuclideanDistance(Point *other);
};
POLYGLOT_DECLARE_TYPE(Point)
class XtendPoint : public Point {
private:
int z;
public:
XtendPoint();
int getZ();
void setZ(int val);
int getZ(int constant);
int getX();
};
POLYGLOT_DECLARE_TYPE(XtendPoint)
//class methods
Point::Point() {
x = 0;
y = 0;
}
int Point::getX() {
return x;
}
int Point::getY() {
return y;
}
void Point::setX(int val) {
x = val;
}
void Point::setY(int val) {
y = val;
}
double Point::squaredEuclideanDistance(Point *other) {
double dX = (double) (x - other->x);
double dY = (double) (y - other->y);
return dX * dX + dY * dY;
}
XtendPoint::XtendPoint() {
z = 0;
}
int XtendPoint::getZ() {
return z;
}
void XtendPoint::setZ(int dZ) {
z = dZ;
}
int XtendPoint::getZ(int constantOffset) {
return z + constantOffset;
}
int XtendPoint::getX() {
return x * 2;
}
//functions
EXTERN void *allocNativePoint() {
Point *ret = (Point *) malloc(sizeof(*ret));
return polyglot_from_Point(ret);
}
EXTERN void *allocNativeXtendPoint() {
XtendPoint *ret = (XtendPoint *) malloc(sizeof(*ret));
return polyglot_from_XtendPoint(ret);
}
EXTERN void swap(Point *p, Point *q) {
Point tmp = *q;
*q = *p;
*p = tmp;
}
EXTERN void freeNativePoint(Point *p) {
free(p);
}
EXTERN void freeNativeXtendPoint(XtendPoint *p) {
free(p);
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://oss.oracle.com/pipermail/graalvm-users/attachments/20210125/8dcdc035/attachment.html
More information about the GraalVM-Users
mailing list