本文假设读者使用cmake方式编写jni代码,并且已经学会基本数据类型的jni传递!
一、传递数组,这里使用byte[]数组举例:
1、首先在java层定义native函数,并且loadLibrary库
static {
System.loadLibrary("linkJNI");
}
public static native byte[] setByteArrayData(byte[] byteArrayData);
2、编写测试类代码,这里就是在Activity加了个TextView,显示jni返回的值,test是在构造函数中调用的
private void test() {
StringBuilder sb = new StringBuilder();
byte[] bytes = JNIUtils.setByteArrayData(new byte[]{11, 22, 33, 44, 55});
for (int i = 0; i < bytes.length; i++) {
sb.append(bytes[i]);
}
tvJni.setText(sb);
}
3、cmakelists.txt文件中
add_library(linkJNI SHARED src/main/cpp/launchScan.cpp)
find_library( log-lib log )
target_link_libraries(linkJNI ${log-lib} )
4、launchScan.cpp文件中实现对应的代码
//jni函数入口,类似main函数
jint JNI_OnLoad(JavaVM* vm,void* reserved){
printf("jni_onload_start");
//注册时在JNIEnv中实现,所以必须首先获取它
JNIEnv* env = NULL;
jint result = -1;
//从JavaVM中获取JNIEnv,一般使用1.4的版本
if(vm->GetEnv((void **)&env,JNI_VERSION_1_4)!=JNI_OK){
return result;
}
result = RegisterNative(env);
printf("RegisterNatives result:%d",result);
printf("jni_onload_end");
return JNI_VERSION_1_4;//必须返回版本,否则加载会失败
}
jint RegisterNative(JNIEnv* env){
//获取映射的Java类
jclass javaClass = env->FindClass(className);
if(javaClass==NULL){
printf("cannot get class : %s\n" ,className);
return -1;
}
return env->RegisterNatives(javaClass,getMethods,sizeof(getMethods)/sizeof(getMethods[0]));
}
const char * className = "com/my_project/test_jni/JNIUtils";
const JNINativeMethod getMethods[] = {
{"getBackTotalNum","(II)I",(void*) getBackTotalNum}
,{"getBackText","(Ljava/lang/String;)Ljava/lang/String;",(void*)getBackText}
,{"setByteArrayData","([B)[B",(void*)setByteArrayData}
};
jbyteArray setByteArrayData(JNIEnv * env,jobject job,jbyteArray byteArry){
//获取数组长度
int byteArryLength = env->GetArrayLength(byteArry);
LOGI("setByteArryrdata,byteArryLength is :%d",byteArryLength);
//获取数组指针
char* byteArray=(char*)env->GetByteArrayElements(byteArry,0);
//申请数组,从指针中取出每一个字符
jbyte arr[byteArryLength];
for(int i =0;i<byteArryLength;i++){
arr[i] = byteArray[i];
LOGI("setByteArryrdata,byteArray is :%d",arr[i]);
}
//再从c代码中取出数组,返回给java
jbyteArray c_result = env->NewByteArray(byteArryLength);
env->SetByteArrayRegion(c_result,0,byteArryLength,arr);
//释放内存
env->ReleaseByteArrayElements(byteArry,byteArray,0);
return c_result;
}
demo很简单,注释基本上看明白流程,跑一遍代码应当就能学会,有问题欢迎大佬们斧正
本文介绍如何使用CMake和JNI在Java与C++间传递数组数据,通过具体实例详细展示了设置与获取字节数组的过程。涵盖Java层函数定义、C++实现、CMake配置及运行测试。

2785

被折叠的 条评论
为什么被折叠?



