当前位置:网站首页>JNI practical notes
JNI practical notes
2022-07-19 05:41:00 【Spring and autumn of Qin and Han Dynasties】
I haven't used it for a long time JNI 了 , Review the basic usage .
cmake To configure
The construction method starts from ndk-build go to cmake, I feel good at the moment .
cmake To configure :
# Minimum setting cmake edition
cmake_minimum_required(VERSION 3.4.1)
project (start)
# name start Dynamic library , The resulting libstart.so
add_library(start SHARED src/main/cpp/start.cpp)
# Find the local library
find_library(xter start)
# Native library and log Log related Library
target_link_libraries(start ${log-lib})
Mainly add_library and target_link_libraries We need to pay attention to ;
add_library Used to name and generate libraries , Here is the single file , If there are multiple files , Similar to
file(GLOB_RECURSE SRC_C "*.cpp")
add_library(start SHARED ${SRC_C})
The way to configure , And if you need to generate multiple libraries , Add again add_library The configuration can be ;
target_link_libraries Link library for configuring the library generated above , It can be simply understood as configuration " rely on ", It's used here log Log Library , So you need to configure the log Library , Empathy , If there are other libraries that need to configure dependencies , Add a similar configuration again .
More detailed configuration instructions can be found cmake Official documents .
Common methods
Create array :
- NewXXXArray
Such as NewIntArray、NewFloatArray And other basic data types , or NewObjectArray Object building array ;
Assign values to arrays :
- SetXXXArrayRegion
Assign values to arrays of basic data types , Such as SetIntArrayRegion、SetFloatArrayRegion; - SetObjectArrayElement
Assign values to an array of objects
Get array value :
- GetXXXArrayElements
Get the pointer of the basic data type array , Such as GetIntArrayElements, Generally, it needs to cooperate with the corresponding release methods, such as ReleaseIntArrayElements Use ; - GetObjectArrayElement
Get the pointer of the object array , The same as above ; - GetXXXArrayRegion
obtain ( Copy ) Array pointer to a range of arrays ;
Create objects :
- FindClass
Find the object path , You must have a full classpath , Such as FindClass(“java/util/ArrayList”); - GetMethodID
Get the methods in the class , Such as GetMethodID(cls_ArrayList, “”, “()V”); - NewObject/AllocObject
Call the constructor to create the object , Such as NewObject(cls_ArrayList, construct, “”);
For some classes , It can also be used directly AllocObject Create objects ; - GetFieldID/GetStaticFieldID
Get a member variable , Such as GetFieldID(jc, “address”, “java/lang/String”);
GetStaticFieldID Is to get static member variables , Use the same way ; - SetObjectField/SetStaticObjectField
Assign value to member variable , Such as SetObjectField(profile, field_address, env->NewStringUTF(“ Ask is in the Forbidden City ”)); - CallXXXMethod
Method of calling class , Such as CallBooleanMethod、CallVoidMethod etc. , Each data type also has extended derivation methods, such as CallBooleanMethodA、CallBooleanMethodV, It's the same thing , It's just that there are different ways to pass parameters ;
Use scenarios
The creation of arrays
public static native int[] getIntArray(int size);
Use NewXXXArrray New array , Then assign a value ;
JNIEXPORT jintArray JNICALL
Java_com_xter_jnipractice_SomeFunc_getIntArray(JNIEnv *env, jclass o,
jint size) {
jintArray array;
array = env->NewIntArray(size);
for (int i = 0; i < size; i++) {
env->SetIntArrayRegion(array, i, 1, &i);
}
return array;
}
Focus on SetIntArrayRegion Use , Arrays of other data types are used in the same way :
void SetIntArrayRegion(jintArray array, jsize start, jsize len, const jint* buf)
void SetCharArrayRegion(jcharArray array, jsize start, jsize len, const jchar* buf)
void SetByteArrayRegion(jbyteArray array, jsize start, jsize len, const jbyte* buf)
void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, const jfloat* buf)
void SetLongArrayRegion(jlongArray array, jsize start, jsize len, const jlong* buf)
void SetShortArrayRegion(jshortArray array, jsize start, jsize len, const jshort* buf)
void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, const jdouble* buf)
void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, const jboolean* buf)
String usage
public static native String[] getStringArray(int size);
For general scenarios ,NewStringUTF Sufficient use , Pass in char* that will do ;
Here is to create a string array , You need to declare the object type as String;
JNIEXPORT jobjectArray JNICALL
Java_com_xter_jnipractice_SomeFunc_getStringArray(JNIEnv *env, jclass o,
jint size) {
jclass jc = env->FindClass("java/lang/String");
jobjectArray array;
array = env->NewObjectArray(size, jc, NULL);
const char *s[] = {
" I ", " you ", " He ", " it ", " she "};
for (int i = 0; i < size; i++) {
jstring ss = env->NewStringUTF(s[i % 5]);
env->SetObjectArrayElement(array, i, ss);
}
return array;
}
Create complex objects
The custom object is :
public class Profile {
public String address;
public String school;
public String degree;
public String phoneNumber;
public int salary;
public ArrayList<String> experience;
}
native Method is :
public static native Profile genProfile();
Then according to the above steps , Find the classpath first , And get its member variables :
jclass jc = env->FindClass("com/xter/jnipractice/entity/Profile");
jfieldID field_address = env->GetFieldID(jc, "address", "java/lang/String");
jfieldID field_school = env->GetFieldID(jc, "school", "java/lang/String");
jfieldID field_degree = env->GetFieldID(jc, "degree", "java/lang/String");
jfieldID field_phoneNumber = env->GetFieldID(jc, "phoneNumber", "java/lang/String");
jfieldID field_salary = env->GetFieldID(jc, "salary", "I");
jfieldID field_experience = env->GetFieldID(jc, "experience", "java/util/ArrayList");
Be careful GetFieldID The third parameter is the type descriptor passed in ;
Basic data types are capitalized , except 2 A special ——boolean->Z,long->J;
Void The corresponding is V, The array corresponds to [;
Other reference types are “L Class full name ;“ form , Such as "Ljava/lang/String;”, But after testing GetFieldID The verification here is not so strict , So use it directly "java/lang/String" It's OK, too ;
jclass cls_ArrayList = env->FindClass("java/util/ArrayList");
jmethodID construct = env->GetMethodID(cls_ArrayList, "<init>", "()V");
jobject obj_ArrayList = env->NewObject(cls_ArrayList, construct, "");
jmethodID arrayList_add = env->GetMethodID(cls_ArrayList, "add", "(Ljava/lang/Object;)Z");
env->CallBooleanMethod(obj_ArrayList, arrayList_add, env->NewStringUTF(" Great wall tiling "));
env->CallBooleanMethod(obj_ArrayList, arrayList_add, env->NewStringUTF(" Hydrogen bomb polishing "));
env->CallBooleanMethod(obj_ArrayList, arrayList_add, env->NewStringUTF(" Space elevator "));
Then create a List aggregate , Also call its constructor to create List object , Then call it. add Method to add a value ;
Note here GetMethodID The last parameter is also the incoming type description signature , by “( Parameter type ) Return type ” Format , there list Of add The parameter type of the method is Object, The return value type is boolea So it's written as "(Ljava/lang/Object;)Z";
And the above construction method is parameterless , therefore NewObject The last parameter is null , If it is called with parameters , Then pass the corresponding parameters , Such as :
jclass cls_ArrayList = env->FindClass("java/util/ArrayList");
jmethodID construct = env->GetMethodID(cls_ArrayList, "<init>", "(I)V");
jobject obj_ArrayList = env->NewObject(cls_ArrayList, construct, 3);
Here we call ArrayList Another parametric construction method , Into int;
Finally, set the value of the custom object :
jobject profile = env->AllocObject(jc);
jstring address = env->NewStringUTF(" Ask is in the Forbidden City ");
env->SetObjectField(profile, field_address, address);
env->SetObjectField(profile, field_experience, obj_ArrayList);
operation byte Array
Custom object :
public class Secret {
public byte[] order = new byte[1];
public byte[] len = new byte[4];
public byte[] plan;
}
native Method is :
public static native Secret genSecret(byte[] buffer);
The incoming data is :
byte[] b1 = BytesUtils.intTo1Bytes(1);
byte[] b2 = BytesUtils.intTo4Bytes(45);
byte[] b3 = " Members said that Hong Kong's education must learn from the motherland ".getBytes();
byte[] buffer = BytesUtils.mergerBytes(b1,b2,b3);
Log.i("jni", "Secret=" + SomeFunc.genSecret(buffer));
Start building objects , The first is also to find the object , Get the member variables :
jclass jc = env->FindClass("com/xter/jnipractice/entity/Secret");
jfieldID field_order = env->GetFieldID(jc, "order", "[B");
jfieldID field_len = env->GetFieldID(jc, "len", "[B");
jfieldID field_plan = env->GetFieldID(jc, "plan", "[B");
Then build buffer, From source byte[] Take from ( Copy ) value :
jbyte *bufOrder = (jbyte *) malloc(sizeof(jbyte) * 1);
jbyte *bufLen = (jbyte *) malloc(sizeof(jbyte) * 4);
memset(bufOrder, 0, sizeof(jbyte) * 1);
memset(bufLen, 0, sizeof(jbyte) * 4);
env->GetByteArrayRegion(buffer, 0, 1, bufOrder);
env->GetByteArrayRegion(buffer, 1, 4, bufLen);
unsigned int len = byte2int(bufLen, 4);
jbyte *bufPlan = (jbyte *) malloc(sizeof(jbyte) * len);
LOGD("content len = %d",len);
memset(bufPlan, 0, sizeof(jbyte) * len);
env->GetByteArrayRegion(buffer, 5, len, bufPlan);
Then create byte[], With buffer assignment :
jbyteArray arrayOrder = env->NewByteArray(1);
jbyteArray arrayLen = env->NewByteArray(4);
jbyteArray arrayPlan = env->NewByteArray(len);
env->SetByteArrayRegion(arrayOrder, 0, 1, bufOrder);
env->SetByteArrayRegion(arrayLen, 0, 4, bufLen);
env->SetByteArrayRegion(arrayPlan, 0, len, bufPlan);
Finally, assign values to objects one by one :
jobject secret = env->AllocObject(jc);
env->SetObjectField(secret, field_order, arrayOrder);
env->SetObjectField(secret, field_len, arrayLen);
env->SetObjectField(secret, field_plan, arrayPlan);
Record the common methods as a whole , See source code Portal .
边栏推荐
- 9.数据仓库搭建之DIM层搭建
- Use of MySQL
- 软件过程与管理复习(七)
- 1. Dongsoft Cross - Border E - commerce Data Warehouse Requirement specification document
- Review my first job search trip
- 跨域和处理跨域
- 5. Business analysis of data acquisition channel construction
- Scala primary practice - statistics of mobile phone traffic consumption (1)
- 模型时间复杂度和空间复杂度
- 1 SparkSQL概述
猜你喜欢

微信小程序的页面导航

4.东软跨境电商数仓项目--数据采集通道搭建之用户行为数据采集通道搭建(2022.6.1-2022.6.4)

USB转TTL CH340模块安装(WIN10)

Pointnet++代码详解(七):PointNetSetAbstractionMsg层

6.数据仓库搭建之数据仓库设计

12. Ads layer construction of data warehouse construction

E-commerce user behavior real-time analysis system (flink1.10.1)

Could not locate zlibwapi.dll. Please make sure it is in your library path

软件过程与管理复习(九)

Custom components of wechat applet
随机推荐
List与Map
Use ide to make jar package
11. DWS layer construction of data warehouse construction
Application of recursion
JNA加载DLL及在jar中的运用
软件过程与管理复习(八)
6.数据仓库搭建之数据仓库设计
多模态融合方法总结
JVM learning
8. ODS layer construction of data warehouse
Time difference calculation
[first launch in the whole network] will an abnormal main thread cause the JVM to exit?
微信小程序的页面导航
9.数据仓库搭建之DIM层搭建
dlib库和.dat文件地址
跨域和处理跨域
使用Gson解析错误json数据
Preorder, middle order and postorder traversal of binary tree
Mysql逗号分隔的数据进行分行
About terminating tasks in thread pool