JNI - 如何填充从C ++传递到Java

时间:2017-04-30 10:33:17

标签: java android c++ android-ndk java-native-interface

我需要将空字符串从c ++发送到java,java函数应填充此字符串,以便c ++可以使用它。

我不希望Java代码返回值。我希望它填充收到的字符串。

我想使用StringBuilder,这就是我的java函数的样子:

private static void setValue(StringBuilder param) {
param.append(value);
}

这就是我的C ++代码的样子:

jclass class = env->FindClass("class");
jmethodID method = env->GetStaticMethodID(class, "fillValue", "
(Ljava/lang/StringBuilder;)V");

我应该向该功能发送什么以便它能够正常工作? 我尝试发送jstring但它不起作用。

更新 在c ++方面尝试了以下代码,但它没有用:

char* str;
jstring string = env->NewStringUTF( str );

env->CallStaticObjectMethod(class,method, string);
const char* test = env->GetStringUTFChars(string, 0);

1 个答案:

答案 0 :(得分:3)

我建议使用byte[]这是一个可变类型,而不是跳过创建StringBuilder传递它的箍,然后在你找回它时调用toString 。或者编码时遇到问题。

您可以像这样创建byte[]

jclass mainClass = env->FindClass("Main");
jmethodID method = env->GetStaticMethodID(mainClass, "setValue", "([B)V");

jbyteArray bytes = env->NewByteArray(7);
env->CallStaticVoidMethod(mainClass, method, bytes);
const char* str = (char*) env->GetByteArrayElements(bytes, 0);

printf(str);

//... use here

env->ReleaseByteArrayElements(bytes, (jbyte*) str, JNI_ABORT);

然后你可以像这样填写Java:

public static void setValue(byte[] val) {
    String someString = "Hello!"; // some string
    byte[] bytes = someString.getBytes(StandardCharsets.US_ASCII);
    System.arraycopy(bytes, 0, val, 0, bytes.length);
}

后来我意识到你也可以使用直接字节缓冲区,这可能比使用byte[]更简单。它允许您在任意字节块上创建Java可用视图:

jmethodID method = env->GetStaticMethodID(mainClass, "setValue", "(Ljava/nio/ByteBuffer;)V");

const int buff_size = 1024;
char buff[buff_size]; // Creating a view over this block of memory
env->CallStaticVoidMethod(mainClass, method, env->NewDirectByteBuffer(buff, buff_size));
//... use buff

在Java中:

public static void setValue(ByteBuffer buff) {
    String someString = "Hello!";
    buff.put(someString.getBytes(StandardCharsets.US_ASCII));
}