3

I am struggling with a basic problem. I am trying to call a .dll-function from Java with the following signature:

int function(double* a, double b);

My problem is that I don't know how to use the double* a parameter in Java and how to print the manipulated value after the function call is done.

Jawa
  • 2,336
  • 6
  • 34
  • 39
wurmi
  • 333
  • 5
  • 18
  • 1
    possible duplicate of [how to pass pointers from java to C in JNI?](http://stackoverflow.com/questions/10381773/how-to-pass-pointers-from-java-to-c-in-jni) – user1 Sep 11 '15 at 09:57
  • I have tried just to pass the variables as simple doubles. This function need to be called by reference becase variable a is also the return value. The int value is just an error code. – wurmi Sep 11 '15 at 11:08
  • JNA's [`DoubleByReference`](https://jna.java.net/nonav/javadoc/com/sun/jna/ptr/DoubleByReference.html) is provided for this purpose, although you can also use a primitive array. – technomage Sep 11 '15 at 13:27

2 Answers2

6

I think for the simplest case of just getting an output back use a double [] with length of 1.

This was my java file (usefunc.java) :

public class usefunc {

    static {
        System.loadLibrary("usefunc");
    }
    public native int function(double a[], double b);

    public static void main(String args[]) {
        double a[] = new double[1];
        new usefunc().function(a,1.0);
        System.out.println("a[0] = " + a[0]);
    }
}

This was my C++ file (usefunc.cpp) :

#include <jni.h>

extern "C" {
    JNIEXPORT jint JNICALL Java_usefunc_function
    (JNIEnv *env, jobject obj, jdoubleArray a, jdouble b);
    int function(double *a, double b);
}

int function(double* a, double b) {
    *a = 77.7;
    return 0;
}

/*
 * Class:     usefunc
 * Method:    function
 * Signature: ([DD)I
 */
JNIEXPORT jint JNICALL Java_usefunc_function
(JNIEnv *env, jobject obj, jdoubleArray a, jdouble b) {
    jboolean iscopy;
    double *nativeA = env->GetDoubleArrayElements(a, &iscopy);
    jint ret = function(nativeA, b);
    env->ReleaseDoubleArrayElements(a, nativeA, 0);
    return ret;
}

Compiled with:

 g++ -I /usr/local/jdk1.8.0_60/include/ -I /usr/local/jdk1.8.0_60/include/linux/ -shared usefunc.cpp  -o libusefunc.so
 javac usefunc.java

Ran with:

 java usefunc

produces:

 a[0] = 77.7
WillShackleford
  • 6,918
  • 2
  • 17
  • 33
3

With JNA, avoiding any native compilation beyond the target shared library:

public class usefunc {

    static {
        Native.register("usefunc");
    }
    public static native int function(double a[], double b);
    public static native int function(DoubleByReference dp, double b);

    public static void main(String args[]) {
        double a[] = new double[1];
        usefunc.function(a,1.0);
        System.out.println("a[0] = " + a[0]);

        DoubleByReference dp = new DoubleByReference();
        usefunc.function(dp,1.0);
        System.out.println("dp = " + dp.getValue());
    }
}
technomage
  • 9,861
  • 2
  • 26
  • 40