jni整理
方法命名规则
JNIEXPORT jstring JNICALL Java_com_zkhero_jnitestdemo_JNIUtils_getTopicMsgFromJNI(JNIEnv *env, jclass clazz, jstring topic) ; //JNIEXPORT和JNICALL分别用于在Windows下标明该函数导出在外部可以调用和用于约束函数入栈顺序和堆栈清理的规则,在编译到Linux环境的动态库时可用省略 //jobect 是方法的返回类型 //函数名的规则是Java_包名_类名_方法名 //方法的形参列表,第一个是JNIEnv *env, 代表的是JNI 函数表指针 //第二个对应的Java方法是实例方法,第二个形参为 jobject instance,代表的是拥有该Java实例方法的实例。若对应的是Java方法是静态方法,第二个形参为jclass cls,代表的是该方法所属的类
java基础数据类型的映射(在native中怎么写)
typedef uint8_t jboolean; /* unsigned 8 bits 对应java boolean*/ typedef int8_t jbyte; /* signed 8 bits 对应java byte*/ typedef uint16_t jchar; /* unsigned 16 bits 对应java char*/ typedef int16_t jshort; /* signed 16 bits 对应java short*/ typedef int32_t jint; /* signed 32 bits 对应java int*/ typedef int64_t jlong; /* signed 64 bits 对应java long*/ typedef float jfloat; /* 32-bit IEEE 754 对应java float*/ typedef double jdouble; /* 64-bit IEEE 754 对应java double*/
jni返回ArrayList自定义对象list
//本地方法
public static native ArrayList getNodesFromJNI(String topic);
//cpp 方法
extern "C"
JNIEXPORT jobject JNICALL
Java_com_zkhero_jnitestdemo_JNIUtils_getNodesFromJNI(JNIEnv *env, jclass clazz, jstring topic)
{
jclass cls_ArrayList = env->FindClass("java/util/ArrayList");
jmethodID construct = env->GetMethodID(cls_ArrayList, "<init>", "()V");
jobject obj_ArrayList = env->NewObject(cls_ArrayList, construct, "");
//获取ArrayList对象的add()的methodID
jmethodID arrayList_add = env->GetMethodID(cls_ArrayList, "add", "(Ljava/lang/Object;)Z");
//定义写死数据返回
char *node[7] = {
"/is_lane",
"/map_server/Publib/fsfd/RangeData",
"/kyber_sim_map_server",
"/lane_cam_0",
"/lcPriodf/gfdgrityArray",
"/lcTargetL/fds/aneArray",
"/lka/motion/gd_plan"};
jclass cls_node = env->FindClass("com/huawei/jnitestdemo/NodeInfo");
jmethodID construct_node = env->GetMethodID(cls_node, "<init>", "()V");
int i;
for (i = 0; i < 7; i++)
{
jobject obj_node = env->NewObject(cls_node, construct_node, "");
jfieldID node_name = env->GetFieldID(cls_node, "name", "Ljava/lang/String;");
jfieldID node_topic = env->GetFieldID(cls_node, "topic", "Ljava/lang/String;");
env->SetObjectField(obj_node, node_name, env->NewStringUTF(node[i]));
env->SetObjectField(obj_node, node_topic, env->NewStringUTF("topicData"));
env->CallObjectMethod(obj_ArrayList, arrayList_add, obj_node);
}
return obj_ArrayList;
}
native层获取java自定义数据类
//从Java层传递NodeInfo对象到Native
JNIEXPORT void JNICALL
Java_com_zkhero_jnitestdemo_JNIUtils_setCurrentNode(JNIEnv *env, jclass clazz, jobject info) {
jclass booCls = env->GetObjectClass(info); //获得java对象的引用
if(booCls == NULL) {
LOGD("book is null");
// 必须要return
return;
}
//env->GetFieldID,该方法能获取到对象字段的引用,最后一个参数参见上表
jfieldID nameField = env->GetFieldID(booCls,"name","Ljava/lang/String;");
jfieldID yearField = env->GetFieldID(booCls, "year","I");
//env->GetIntField得到字段对应的值
jstring name = (jstring)env->GetObjectField(info, nameField);
jint year = env->GetIntField(info, yearField);
const char * c_name = env->GetStringUTFChars(name, NULL);
LOGD("name:%s", c_name);
LOGD("year:%d", year);
env->ReleaseStringUTFChars(name, c_name);
}
/*******nodeinfo对象********/
public class NodeInfo
{
public String name;
public int year;
@Override
public String toString()
{
return "NodeInfo{" +
"name='" + name + '\'' +
", year='" + year + '\'' +
'}' +"\n";
}
}
后面继续新增
本文详细解析了JNI中方法命名的规则,包括如何使用正确的前缀和后缀来标识函数,以及本地方法如何与Java方法相对应。同时,深入介绍了基本数据类型在JNI中的映射方式,以及如何在C/C++中处理Java的复杂数据结构,如ArrayList和自定义对象。

947

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



