如何通过JNI将java CharSequence转换为c ++ char *

时间:2017-07-07 14:54:39

标签: java c++ java-native-interface charsequence

我觉得这应该有一个简单的答案,因为我可以使用java String轻松完成,但是CharSequence出了点问题。我的java代码初始化cppGenerator,将functionBlock object传递给generateImplementation method,然后返回CharSequence。这是我的代码:

jobject fBlock = env->CallObjectMethod(structuredTextModel, getFunction);
jclass CPPGenerator = lookForClass(env, "Path/CPPGenerator");
jobject CPPGeneratorImpl = invokeClassObj(env, CPPGenerator);
    jmethodID generateImplementation = env->GetMethodID(CPPGenerator, "generateImplementation", "(LPath/FunctionBlock;)Ljava/lang/CharSequence;");
jobject mid = env->CallObjectMethod(CPPGeneratorImpl, generateImplementation, fBlock);
jstring jresult = (jstring)mid;
char* result = (char*)env->GetStringUTFChars(jresult, 0);

使用String时,此逻辑对我有用,但此函数返回CharSequence。没有类,对象或方法返回null。该程序在jni.h尝试呼叫GetStringUTFChars时崩溃。所以我知道我不能将此方法用于CharSequence。是否只有一种我缺少的jni方法,或者我是否必须为CharSequence做一些完全不同的事情?

2 个答案:

答案 0 :(得分:1)

您无法将mid转变为jstring并致电GetStringUTFChars(因为mid可能不是String,这似乎是GetStringUTFChars案子)。对于CharSequenceString没有像charAt那样的便捷方法。

您必须以不方便的方式拨打jclass cCharSequence = env->FindClass("java/lang/CharSequence"); jmethodID mLength = env->GetMethodID(cCharSequence, "length", "()I"); jmethodID mCharAt = env->GetMethodID(cCharSequence, "charAt", "(I)C"); int length = env->CallIntMethod(mid, mLength); std::string str; str.reserve(length); for(int i = 0; i < length; i++) { str += env->CallCharMethod(mid, mCharAt, i); } // use 'str.c_str()'...

017-07-07T12:07:22.492+0000 I REPL     [replication-1] Starting initial sync (attempt 10 of 10)
2017-07-07T12:07:22.501+0000 I REPL     [replication-1] sync source candidate: mongo-2.blabla.com:27017
2017-07-07T12:07:22.501+0000 I STORAGE  [replication-1] dropAllDatabasesExceptLocal 1
2017-07-07T12:07:22.501+0000 I REPL     [replication-1] ******
2017-07-07T12:07:22.501+0000 I REPL     [replication-1] creating replication oplog of size: 6548MB...
2017-07-07T12:07:22.504+0000 I STORAGE  [replication-1] WiredTigerRecordStoreThread local.oplog.rs already started
2017-07-07T12:07:22.505+0000 I STORAGE  [replication-1] The size storer reports that the oplog contains 0 records totaling to 0 bytes
2017-07-07T12:07:22.505+0000 I STORAGE  [replication-1] Scanning the oplog to determine where to place markers for truncation
2017-07-07T12:07:22.519+0000 I REPL     [replication-1] ******
2017-07-07T12:07:22.521+0000 I REPL     [replication-1] Initial sync attempt finishing up.
2017-07-07T12:07:22.521+0000 I REPL     [replication-1] Initial Sync Attempt Statistics: { failedInitialSyncAttempts: 9, maxFailedInitialSyncAttempts: 10, initialSyncStart: new Date(1499429233163), initialSyncAttempts: [ { durationMillis: 0, status: "CommandNotFound: error while getting last oplog entry for begin timestamp: no such cmd: find", syncSource: "mongo-2.blabla.com:27017" }, { durationMillis: 0, status: "CommandNotFound: error while getting last oplog entry for begin timestamp: no such cmd: find", syncSource: "mongo-2.blabla.com:27017" }, { durationMillis: 0, status: "CommandNotFound: error while getting last oplog entry for begin timestamp: no such cmd: find", syncSource: "mongo-2.blabla.com:27017" }, { durationMillis: 0, status: "CommandNotFound: error while getting last oplog entry for begin timestamp: no such cmd: find", syncSource: "mongo-2.blabla.com:27017" }, { durationMillis: 0, status: "CommandNotFound: error while getting last oplog entry for begin timestamp: no such cmd: find", syncSource: "mongo-2.blabla.com:27017" }, { durationMillis: 0, status: "CommandNotFound: error while getting last oplog entry for begin timestamp: no such cmd: find", syncSource: "mongo-2.blabla.com:27017" }, { durationMillis: 0, status: "CommandNotFound: error while getting last oplog entry for begin timestamp: no such cmd: find", syncSource: "mongo-2.blabla.com:27017" }, { durationMillis: 0, status: "CommandNotFound: error while getting last oplog entry for begin timestamp: no such cmd: find", syncSource: "mongo-2.blabla.com:27017" }, { durationMillis: 0, status: "CommandNotFound: error while getting last oplog entry for begin timestamp: no such cmd: find", syncSource: "mongo-2.blabla.com:27017" } ] }
2017-07-07T12:07:22.521+0000 E REPL     [replication-1] Initial sync attempt 
failed -- attempts left: 0 cause: CommandNotFound: error while getting last 
oplog entry for begin timestamp: no such cmd: find
2017-07-07T12:07:22.521+0000 F REPL     [replication-1] The maximum number 
of retries have been exhausted for initial sync.
2017-07-07T12:07:22.522+0000 E REPL     [replication-0] Initial sync failed, 

shutting down now. Restart the server to attempt a new initial sync.
2017-07-07T12:07:22.522+0000 I -        [replication-0] Fatal assertion 40088 CommandNotFound: error while getting last oplog entry for begin timestamp: no such cmd: find at src/mongo/db/repl/replication_coordinator_impl.cpp 632

答案 1 :(得分:0)

为什么不直接使用toString

jclass clzCharSequence = env->GetObjectClass(mid);
jmethodID toString = env->GetMethodID(clzCharSequence, "toString", "()Ljava/lang/String;");
jobject s = env->CallObjectMethod(mid, toString);
const char* cstr = env->GetStringUTFChars(static_cast<jstring>(s), NULL);
// do something with cstr
env->ReleaseStringUTFChars(static_cast<jstring>(s), cstr);
相关问题