[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