Sqlite JNI:JNI本地引用表中最后10个条目出错。

Sqlite 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

我正在尝试开发原生sqlite库,这将有助于访问shA256加密sqlite数据库。它在查询结果不大时工作,但如果查询结果记录计数大于JNI返回错误“本地引用表溢出512个条目”。请检查下面我的代码示例

jobjectArray行=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;
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
,但创建字符串数组对象数组是您清除本地引用计数的地方。