Sqlite JNI:JNI本地引用表中最后10个条目出错。
我正在尝试开发原生sqlite库,这将有助于访问shA256加密sqlite数据库。它在查询结果不大时工作,但如果查询结果记录计数大于JNI返回错误“本地引用表溢出512个条目”。请检查下面我的代码示例 jobjectArray行=NULLSqlite JNI:JNI本地引用表中最后10个条目出错。,sqlite,java-native-interface,Sqlite,Java Native Interface,我正在尝试开发原生sqlite库,这将有助于访问shA256加密sqlite数据库。它在查询结果不大时工作,但如果查询结果记录计数大于JNI返回错误“本地引用表溢出512个条目”。请检查下面我的代码示例 jobjectArray行=NULL sqlite3_stmt *statement; if(sqlite3_prepare_v2(db, sdbquery, -1, &statement, 0) == SQLITE_OK) { int cols = sqlite3_colum
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;
sqlite3_stmt*语句;
if(sqlite3\u prepare\u v2(db,sdbquery,-1,&语句,0)=SQLITE\u OK)
{
int cols=sqlite3\u column\u count(语句);
int结果=0;
jboolean flag=JNI_TRUE;
int=0;
jclass stringClass=(*env)->FindClass(env,“java/lang/String”);
而(1)
{
结果=sqlite3_步骤(语句);
LOGV(“结果计数:%d\n”,结果);
如果(结果==SQLITE_行)
{
jobjectArray行=(*env)->NewObjectArray(env,cols,stringClass,0);
int col;
对于(col=0;colNewStringUTF(env,”);
}否则{
VALTR=(*env)->NewStringUTF(env,val);
}*/
//(*env)->SetObjectArrayElement(env、row、col、valStr);
(*env)->SetObjectArrayElement(env、row、col、s);
(*env)->DeleteLocalRef(env,s);
//(*env)->释放StringUTFChars(env、VALTR、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,世界其他地区);
crow++;
}
其他的
{
打破
}
}
sqlite3_最终确定(声明);
}否则{
LOGV(“SQL错误:%s\n”,sqlite3_errmsg(db));
无sqlite3_(zErrMsg);
sqlite3_关闭(db);
返回NULL;
}
(*env)->ReleaseStringUTFChars(env、dbquery、sdbquery);
(*env)->ReleaseStringUTFChars(env、dbpath、sdbString);
(*env)->发布StringUTFChars(env、dbkey、sdbkey);
sqlite3_关闭(db);
返回行;
我看不出如何用简单的C转换构造jstring
对象。行:
jstring s = (const char*)sqlite3_column_text(statement, col);
导致内存损坏,伊姆霍
你应使用:
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\u rows
是否有一些东西不能通过JDBC在Java中完成?不确定您在哪里填充count\u rows
,但创建字符串数组对象数组是您清除本地引用计数的地方。