jni指针和堆栈注意

来源:互联网 发布:现货看盘软件 编辑:程序博客网 时间:2024/05/17 22:54

注意

1、c中指针可以直接转为java里的int值,都是32位无损失。

2、循环里要注意释放本地引用,因为循环太多或不可预知,容易溢出,你没有做着咯额异常处理,jvm会直接退出,看不到打印堆栈信息的,所以使用jni时如果程序没有打印就无故退出,就检查下本地方法。

3、long 对应J不是L,会给出打印信息提示的。


事例:

事例1、转成long了,它在java里是64位的,这个文件指针,我在java函数作用域是有效的,递归调用也可以,所以,不会被回收,需要手动关闭资源。

jlong Java_fang_android_OS_opendir(JNIEnv* env, jobject clazz, jstring jPath){__android_log_print(ANDROID_LOG_INFO,LOG_TAG, "");ScopedUtfChars path(env,jPath);//li(path);DIR* d = NULL;d = opendir(path);__android_log_print(ANDROID_LOG_INFO,LOG_TAG,"sizeof(DIR*) = %d, %p", sizeof(DIR*), d);//li("sizeof(DIR*) = %d, %p", sizeof(DIR*), d);return PtrToLong(d);}



//readdir() 不是线程安全的,因为所返回的结构是存储在函数库中的一个静态变量。//大多数现代的 UNIX 系统都具有线程安全的 readdir_r(),如果您正在编写线程代码,可以使用这个函数作为替代。jstring Java_fang_android_OS_readdir(JNIEnv* pEnv, jobject clazz, jlong dir, jintArray fileinfo){dirent dirEntry, *entryPtr;int retval = readdir_r((DIR*)(long)dir, &dirEntry, &entryPtr);if (entryPtr == NULL || 0 != retval)return NULL;//dirent *pDirEntry = readdir((DIR*)(long)dir);//if (pEnv->ExceptionCheck()) {//            return NULL;//    }//if(NULL== pDirEntry){//return NULL;//}//li(pDirEntry->d_name);if(fileinfo != 0){jint* pFileInfo = (jint*)pEnv->GetPrimitiveArrayCritical(fileinfo, 0);if (pFileInfo){int len = pEnv->GetArrayLength(fileinfo);if (len >= 4){pFileInfo[0] = dirEntry.d_ino;pFileInfo[1] = dirEntry.d_off;pFileInfo[2] = dirEntry.d_reclen;pFileInfo[3] = dirEntry.d_type;}pEnv->ReleasePrimitiveArrayCritical(fileinfo, pFileInfo, 0);}}return pEnv->NewStringUTF(dirEntry.d_name);}


jint Java_fang_android_OS_closedir(JNIEnv* env, jobject clazz, jlong dir){int ret = closedir((DIR*)(long)dir);return static_cast<jint>(ret);}



事例2:

。还是官方代码,稍微转换一下,少依赖其他文件,这里ScopedLocalRef作用域完了会自动释放NewStringUTF的。

// Translate the intermediate form into a Java String[].for (size_t i = 0; i < numEntries; ++i) {if (answer) {ScopedLocalRef<jstring> localFileNameRef(pEnv, pEnv->NewStringUTF(currentEntry->pathEntry));//jstring jstrFileName = pEnv->NewStringUTF(currentEntry->pathEntry);if (pEnv->ExceptionCheck()) {return NULL;}//pEnv->SetObjectArrayElement(answer, i, jstrFileName);pEnv->SetObjectArrayElement(answer, i, localFileNameRef.get());if (pEnv->ExceptionCheck()) {return NULL;}//pEnv->DeleteLocalRef(jstrFileName);}free((void *) currentEntry);currentEntry = currentEntry->next;//pEnv->ReleaseStringUTFChars(s, currentEntry->pathEntry);//pEnv->DeleteLocalRef( s);}


事例3,注册本地函数时

{"opendir","(Ljava/lang/String;)J",(void*)Java_fang_android_OS_opendir},{"closedir","(J)I",(void*)Java_fang_android_OS_closedir},{"readdir","(J[I)Ljava/lang/String;",(void*)Java_fang_android_OS_readdir},


0 0
原创粉丝点击