通过jni将每个引用的参数从C ++传递到Java

sos*_*net 4 c++ java parameters java-native-interface reference

我正在尝试通过JNI将每个引用的c ++变量传递给java。首先,我尝试了一些简单的代码:

爪哇

public static void inc(int val) {
  System.out.println("inc called: " + val);
  val++;
}

public static void dec(int val) {
  System.out.println("dec called: " + val);
  val--;
Run Code Online (Sandbox Code Playgroud)

}

这应该简单地使用Java方法增加/减少用c ++代码创建的变量。C ++部分看起来像这样:

C ++

jmethodID jDec = env->GetStaticMethodID(cls, "dec", "(I)V");
jmethodID jInc = env->GetStaticMethodID(cls, "inc", "(I)V");

jint val = 10;

printf("%d\n", val);
env->CallStaticVoidMethod(cls, jDec, &val);
printf("%d\n", val);
env->CallStaticVoidMethod(cls, jInc, val);
printf("%d\n", val);
Run Code Online (Sandbox Code Playgroud)

如您所见,我尝试了每个引用和每个值。

输出量

10
dec called: -401031272
10
inc called: 10
10
Run Code Online (Sandbox Code Playgroud)

在c ++代码中,该值始终为10,在Java中,它要么是地址,要么是值。

如果您能给我一个提示,那就太好了,非常感谢。

Ale*_*nik 5

正如Wojtek所说,Java通过值传递参数。您可以在Java代码中添加返回值

public static int inc2(int val) {
    System.out.println("inc called: " + val);
    return val + 1;
}
Run Code Online (Sandbox Code Playgroud)

然后从C ++调用它:

jmethodID inc2 = env->GetStaticMethodID(cls, "inc2", "(I)I");
jint result = env->CallStaticIntMethod(cls, inc2, val);
printf("inc2: %d\n", result);
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用包装器类

public class IntWrapper {

    private int value;

    public IntWrapper(int value) {
        setInt(value);
    }

    public int getInt() {
        return value;
    }

    public void setInt(int value) {
        this.value = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

以及以下Java方法:

public static void inc3(IntWrapper val) {
    val.setInt(val.getInt()+1);
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以从C ++代码中调用此代码:

// create wrapper object
jclass wrapper = env->FindClass("IntWrapper");
jmethodID constructor = env->GetMethodID(wrapper, "<init>", "(I)V");
jobject wrapperObject = env->NewObject(wrapper, constructor, val);

// print value before increment
jmethodID getInt = env->GetMethodID(wrapper, "getInt", "()I");
jint ret = env->CallIntMethod(wrapperObject, getInt);
printf("Wrapper value: %d\n", ret);

// call inc3
jmethodID inc3 = env->GetStaticMethodID(cls, "inc3", "(LIntWrapper;)V");
env->CallStaticVoidMethod(cls, inc3, wrapperObject);

// print result
ret = env->CallIntMethod(wrapperObject, getInt);
printf("Wrapper value after increment: %d\n", ret);
Run Code Online (Sandbox Code Playgroud)

另外,您可以使用int []代替Wojtek建议的包装器类。