转载地址: http://blog.csdn.net/neo_86/article/details/24931509
注意
1、c中指针可以直接转为java里的int值,都是32位无损失(32位操作系统或者gcc 32编译器)。
2、循环里要注意释放本地引用,因为循环太多或不可预知,容易溢出,你没有做着咯额异常处理,jvm会直接退出,看不到打印堆栈信息的,所以使用jni时如果程序没有打印就无故退出,就检查下本地方法。
3、long 对应J不是L,会给出打印信息提示的(64位操作系统或gcc 64位)。
事例:
事例1、转成long(函数PtrToLong),它在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);
-
-
- DIR* d = NULL;
- d = opendir(path);
- __android_log_print(ANDROID_LOG_INFO,LOG_TAG,"sizeof(DIR*) = %d, %p", sizeof(DIR*), d);
-
- return PtrToLong(d);
- }
-
-
- 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;
-
-
-
-
-
-
-
-
- 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的。
-
- for (size_t i = 0; i < numEntries; ++i) {
- if (answer) {
- ScopedLocalRef<jstring> localFileNameRef(pEnv, pEnv->NewStringUTF(currentEntry->pathEntry));
-
- if (pEnv->ExceptionCheck()) {
- return NULL;
- }
-
- pEnv->SetObjectArrayElement(answer, i, localFileNameRef.get());
- if (pEnv->ExceptionCheck()) {
- return NULL;
- }
-
- }
- free((void *) currentEntry);
- currentEntry = currentEntry->next;
-
-
- }
事例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},