C++11 JNI开发中RAII的应用(二)--JNI函数封装
来源:互联网 发布:nginx http referer 编辑:程序博客网 时间:2024/06/14 19:44
在上一节《C++11 JNI开发中RAII的应用(一)》中我们已经有了一些基本的RAII封装工具,本节就简单了,就是根据需要把一些常用的JNIEnv函数封装成更方便使用的模板函数。
raii_NewGlobalRef
raii_NewGlobalRef
函数顾名思义,就是封装JNIEnv::NewGlobalRef,将一个本地引用的jobject
转为全局引用封装在raii_var
中。
/* 封装JNIEnv::NewGlobalRef 返回jobject对象全局引用(RAII管理) */ template<typename T=jobject,typename TYPE=typename std::conditional<!std::is_same<T,jobject>::value,T,jobject>::type> static raii_var<TYPE> raii_NewGlobalRef(T localRef) { static_assert( std::is_base_of<typename std::remove_pointer<jobject>::type, typename std::remove_pointer<T>::type>::value, "T is not derived from jobject"); return raii_var<TYPE>( [localRef]()->TYPE {return static_cast<TYPE>(getJNIEnv()->NewGlobalRef(localRef));}, [](TYPE &gref) {getJNIEnv()->DeleteGlobalRef(gref);}); }
在调用时,如果不指定T的类型,则返回的raii_var
类中的类型默认为jobject
,否则
下面所有的模板函数都是这个用法。
raii_FindClass_LocalRef & raii_FindClass_GlobalRef
raii_FindClass_LocalRef
和raii_FindClass_GlobalRef
,封装了JNIEnv::FindClass,返回字符串name
指定的类名的jclass
对象,raii_FindClass_LocalRef
返回的是本地引用,raii_FindClass_GlobalRef
返回全局引用。
/* 封装JNIEnv::FindClass 返回jclass对象局部引用(RAII管理) */ static raii_var<jclass> raii_FindClass_LocalRef(const char* name) { assert(nullptr != name); return raii_jobject_env(&JNIEnv::FindClass, name); } /* 封装JNIEnv::FindClass 返回jclass对象全局引用(RAII管理) */ static raii_var<jclass> raii_FindClass_GlobalRef(const char* name) { return raii_NewGlobalRef<jclass>(raii_FindClass_LocalRef(name).get()); }
比如:
auto jstring_class=raii_FindClass_LocalRef("Ljava/lang/String;");//返回String类的jclass对象
raii_GetObjectClass
raii_GetObjectClass
封装JNIEnv::GetObjectClass,返回一个jobject
的jclass
对象
static raii_var<jclass> raii_GetObjectClass(jobject obj) { assert(nullptr != obj); return raii_jobject_env(&JNIEnv::GetObjectClass, obj); }
raii_CallObjectMethod
raii_CallObjectMethod
封装JNIEnv:CallObjectMethod
//通过methodID调用指定的方法 template<typename T=jobject,typename... Args> static raii_var<T> raii_CallObjectMethod( jobject obj, jmethodID methodID, Args&&... args) { return raii_jobject_env<T>(&JNIEnv::CallObjectMethod,obj, methodID,std::forward<Args>(args)...); }//通过name指定的方法名和sig指定的方法签名调用指定的方法 template<typename T=jobject,typename... Args> static raii_var<T> raii_CallObjectMethod( jobject obj, const char *name, const char *sig, Args&&... args) { raii_var<jclass> clazz=raii_GetObjectClass(obj); auto methodID = getJNIEnv()->GetMethodID(clazz.get(), name, sig); assert(nullptr != methodID); return raii_CallObjectMethod<T>(obj,methodID,std::forward<Args>(args)...); }
raii_NewObject
raii_NewObject
封装JNIEnv::NewObject有5个重载函数
//通过constructor指定的jmethodID调用指定的构造方法 template<typename T=jobject,typename... Args> static raii_var<T> raii_NewObject( jclass clazz, jmethodID constructor, Args&&... args) { return raii_jobject_env(&JNIEnv::NewObject,clazz,constructor,std::forward<Args>(args)...); }//通过sig指定的构造方法签名来调用指定的构造方法 template<typename T=jobject,typename... Args> static raii_var<T> raii_NewObject( jclass clazz, const char *sig, Args&&... args) { assert(nullptr != clazz); auto constructor = getJNIEnv()->GetMethodID(clazz, "<init>", nullptr==sig?"void (V)":sig); assert(nullptr != constructor); return raii_NewObject<T>(clazz,constructor,std::forward<Args>(args)...); }//通过class_name指定类名和sig指定的构造方法签名来创建新对象 template<typename T=jobject,typename... Args> static raii_var<T> raii_NewObject( const char * class_name, const char *sig,Args&&... args) { return raii_NewObject<T>(raii_FindClass_LocalRef(class_name).get(),sig,std::forward<Args>(args)...); }//用默认构造方法创建clazz指定的对象 template<typename T=jobject> static raii_var<T> raii_NewObject( jclass clazz) { return raii_NewObject<T>(clazz,(const char *)nullptr); }//用默认构造方法创建clas_name指定的对象 template<typename T=jobject> static raii_var<T> raii_NewObject( const char * class_name) { return raii_NewObject<T>(raii_FindClass_LocalRef(class_name).get()); }
raii_NewByteArray
raii_NewByteArray
封装JNIEnv::NewByteArray,创建指定长度的byte数组
static raii_var<jbyteArray> raii_NewByteArray( jsize len) { return raii_jobject_env(&JNIEnv::NewByteArray, len); }
tojbytearray
调用raii_NewByteArray
将一个C++的字节数组转为java字节数组(jbyteArray
)
/* 将bytes转成raii_var<jbyteArray>对象 */ static raii_var<jbyteArray> tojbytearray(jbyte* bytes, jsize len) { auto byteArray = raii_NewByteArray(len); if (nullptr != bytes) getJNIEnv()->SetByteArrayRegion(byteArray.get(), 0, len, bytes); return byteArray; }
raii_NewStringUTF&raii_NewString
raii_NewStringUTF
封装JNIEnv::NewStringUTF,将一个UTF-8编码的字符串转为java String(jstring
) raii_NewStringUTF
封装JNIEnv::NewString,将一个Unicode 编码的jchar数组转为java String(jstring
)
/* 将UTF-8字符串转成一个raii_var管理的JString对象 */ static raii_var<jstring> raii_NewStringUTF(const char* pStr) { return raii_jobject_env(&JNIEnv::NewStringUTF, pStr); } /* 将Unicode字符串转成一个raii_var管理的JString对象 */ static raii_var<jstring> raii_NewString(const jchar* pStr, jsize len) { return raii_jobject_env(&JNIEnv::NewString, pStr, len); }
raii_GetObjectField
raii_GetObjectField
封装JNIEnv::GetObjectField,返回指定fieldID的对象(jobject
)
/* 封装JNIEnv::GetObjectField 返回T指定的jobject基类对象(RAII管理) */ template<typename T=jobject> static raii_var<T> raii_GetObjectField(jobject obj, jfieldID fieldID) { return raii_jobject_env<T>(&JNIEnv::GetObjectField,obj,fieldID); }
raii_GetObjectArrayElement
raii_GetObjectArrayElement
封装JNIEnv::GetObjectArrayElement,返回对象数组指定下标的java 对象(jobject
)
/* 封装JNIEnv::GetObjectField 返回T指定的jobject基类对象(RAII管理) */ template<typename T=jobject> static raii_var<T> raii_GetObjectArrayElement(jobjectArray array, jsize index) { return raii_jobject_env<T>(&JNIEnv::GetObjectArrayElement,array,index); }
raii_GetByteArrayElements
raii_GetByteArrayElements
封装JNIEnv::GetByteArrayElements,返回java字节数组byte[]
的C++字节数组
static auto raii_GetByteArrayElements(jbyteArray bytes, jint release_mode = JNI_ABORT) -> raii_var<decltype(getJNIEnv()->GetByteArrayElements(bytes, nullptr))> { using type = decltype(getJNIEnv()->GetByteArrayElements(bytes, nullptr)); assert(nullptr != bytes); return raii_var<type>( [bytes]()->type { jboolean isCopy; auto result=getJNIEnv()->GetByteArrayElements(bytes, &isCopy); assert(isCopy); // 调用成功断言 return std::move(result); }, [release_mode,bytes](type &obj) {getJNIEnv()->ReleaseByteArrayElements(bytes, obj, release_mode);}); }
raii_GetStringUTFChars
raii_GetStringUTFChars
封装JNIEnv::GetStringUTFChars,返回java String的UTF-8字符串
static auto raii_GetStringUTFChars( jstring jstr) -> raii_var<decltype(getJNIEnv()->GetStringUTFChars(jstr, nullptr))> { using type = decltype(getJNIEnv()->GetStringUTFChars(jstr, nullptr)); assert(nullptr != jstr); return raii_var<type>([jstr]()->type { jboolean isCopy; auto result=getJNIEnv()->GetStringUTFChars(jstr, &isCopy); assert(isCopy); // 调用成功断言 return std::move(result); }, [jstr](type &obj) {getJNIEnv()->ReleaseStringUTFChars(jstr,obj);}); }
throwByName
throwByName
抛出name指定类名的异常,msg
为异常信息 throwIllegalArgumentException
抛出 java.lang.IllegalArgumentException
异常
void throwByName(const char* name, const char* msg) { auto cls = raii_FindClass_LocalRef(name); /* if cls is NULL, an exception has already been thrown */ if (cls.get() != nullptr) { getJNIEnv()->ThrowNew(cls.get(), name); } else { throw invalid_argument(string("not found java class:").append(name).data()); }}void throwIllegalArgumentException(const char* msg) { throwByName("java/lang/IllegalArgumentException", msg);}
- C++11 JNI开发中RAII的应用(二)--JNI函数封装
- C++11 JNI开发中RAII的应用(三)--JavaClassMirror
- C++11 JNI开发中RAII的应用(一)--制作基础工具
- Android Studio3.0开发JNI流程------JNI中字符串拼接的二种方式(C++)
- [JNI]开发之旅(6)JNI函数中访问java类中对象的属性
- android jni 的编写二 (NDK 开发中动态注册Jni)
- [JNI]开发之旅(7)JNI函数中调用java对象的方法
- cocos2dx 的jni封装
- Android Studio中JNI NDK开发(二)
- JNI接口函数<二>
- JNI接口函数<二>
- JNI接口函数<二>
- JNI接口函数<二>
- JNI接口函数<二>
- JNI中在被调用的C/C++函数中如何访问Java程序中的类,并编写应用实例
- 《Android JNI》05 在JNI中调用Java的函数
- [JNI] 开发实例(2) 编译libwebsocket,封装jni函数,搭建IM通信基础服务
- Android中JNI高级应用 - 本地C代码中创建Java对象及本地JNI对象的保存
- 63岁老人自学单片机 8年做出机器人—兄弟连IT教育
- 如何设计一个 iOS 控件?(iOS 控件完全解析)
- armeabi-v7a armeabi arm64-v8a
- Maven的初步详解
- Spring Security通过URL模式匹配的声明式权限控制
- C++11 JNI开发中RAII的应用(二)--JNI函数封装
- theano学习——基本api
- 各种语言的介绍
- sql server 2008无人值守安装
- Editext特效跟随输入文字展现动画
- winsock错误-头文件包含顺序
- http://blog.csdn.net/ryantang03/article/details/9317499/
- linux安装 并卸载jdk
- ViewPager与其中的子View滑动冲突