我尝试开发Native sqlite Lib,这将有助于访问shA256加密的sqlite db。查询结果不大但是如果查询结果记录计数多,则JNI返回错误“本地引用表溢出512条目”。请查看下面的代码示例。
jobjectArray rows = NULL;
sqlite3_stmt *statement;
if(sqlite3_prepare_v2(db, sdbquery, -1, &statement, 0) == SQLITE_OK)
{
int cols = sqlite3_column_count(statement);
int result = 0;
jboolean flag = JNI_TRUE;
int crow=0;
jclass stringClass= (*env)->FindClass(env, "java/lang/String");
while(1)
{
result = sqlite3_step(statement);
LOGV("RESULT COUNT : %d\n", result);
if(result == SQLITE_ROW)
{
jobjectArray row = (*env)->NewObjectArray(env, cols, stringClass, 0);
int col;
for(col=0;col<cols;col++)
{
jstring s = (const char*)sqlite3_column_text(statement, col);
/*jstring valStr;
if (val == NULL) {
valStr = (*env)->NewStringUTF(env, "");
} else {
valStr = (*env)->NewStringUTF(env, val);
}*/
//(*env)->SetObjectArrayElement(env, row, col, valStr);
(*env)->SetObjectArrayElement(env, row, col, s);
(*env)->DeleteLocalRef(env,s);
//(*env)->ReleaseStringUTFChars(env, valStr,val);
//(*env)->DeleteLocalRef(env,valStr);
}
if(flag == JNI_TRUE) {
flag = JNI_FALSE;
rows = (*env)->NewObjectArray(env, count_rows, (*env)->GetObjectClass(env, row), 0);
}
(*env)->SetObjectArrayElement(env, rows, crow, row);
(*env)->DeleteLocalRef(env,row);
crow++;
}
else
{
break;
}
}
sqlite3_finalize(statement);
}else{
LOGV("SQL error : %s\n", sqlite3_errmsg(db));
sqlite3_free(zErrMsg);
sqlite3_close(db);
return NULL;
}
(*env)->ReleaseStringUTFChars(env, dbquery, sdbquery);
(*env)->ReleaseStringUTFChars(env, dbpath, sdbString);
(*env)->ReleaseStringUTFChars(env, dbkey, sdbkey);
sqlite3_close(db);
return rows;
答案 0 :(得分:0)
我无法看到如何使用简单的C强制转换来构造jstring
对象。这一行:
jstring s = (const char*)sqlite3_column_text(statement, col);
导致内存损坏,imho。
您应该使用:
const char* val = sqlite3_column_text(statement, col);
jstring valStr;
if (val == NULL) {
valStr = (*env)->NewStringUTF(env, "");
} else {
valStr = (*env)->NewStringUTF(env, val);
}
请务必在SetObjectArrayElement
来电后将字符串释放为:
(*env)->ReleaseStringUTFChars(env, valStr,val);
(*env)->DeleteLocalRef(env,valStr);
当您查询类或列数组值时,您不会释放它。
应该是:
jclass rowClass = (*env)->GetObjectClass(env, row);
rows = (*env)->NewObjectArray(env, count_rows, rowClass , 0);
(*env)->DeleteLocalRef(env,rowClass);
此外,正如评论中所见,您应该仔细检查count_rows
的使用情况。