java - JNI - 如何填充从 C++ 传递到 Java 的字符串

标签 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);

最佳答案

我建议使用 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[] 更简单。它允许您在任意字节 block 上创建 Java 可用 View :

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));
}

关于java - JNI - 如何填充从 C++ 传递到 Java 的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43705464/

相关文章:

java - 自定义 ListView 未按应有的方式更新

android - 如何修复 android studio 同步 Gradle 时出现的 'Cannot invoke method buildTypes()' 错误?

android - 市场过滤器,如何排除布局-notlong

c++ - hello-world.cc 样本似乎泄漏了内存

C++:将构造对象的引用传递给构造的成员对象?

Java 8 日期和时间 : parse ISO 8601 string without colon in offset

java - Hibernate - 在插入时填充子实体

java - 使用 BeanComparator 比较 Java Bean

java - Netty:永远不会调用 ChannelRead0

c++ - 完美转发构造函数和删除构造函数