之前实现了简单的jni入门实例, 这篇博客将主要介绍使用jni在c++调用java的属性和方法。
本地方法函数有两个参数,JNIEnv *和jobject,这两个参数非常重要
1.JNI数据类型
为了方便记忆和书写java数据类型与c++数据类型的对应,jni对数据进行封装。具体为下
2.获取java属性和方法
首先需要获取对应的java的类,jni专门定义了jclass类型来表示java的Class类,JNIEvn类中有几个函数取得jclass:
1.jclass FindClass(const char * clsName)----传入完整类名
2.jclass GetObjectClass(jobject obj)------传入类示例
3.jclass GetSuperClass(jclass obj)-------传入Class类
如: jclass string_class=evn->FindClass("java/lang/String")获取String类
得到java类后,访问java的属性或方法首先还要在本地代码中获取java属性的jfieldID和java方法的jmethodID才能进行使用。
使用JNIEvn的
1.GetFieldID/GetMethodID来获取非静态的属性和方法
2.GetStaticFieldID/GetStaticMethodID来获取静态的属性和方法
获取属性参数:(类,属性名,属性签名)
获取方法参数:(类,方法名,方法签名)
我们都知道java能对方法进行重载,为了准确获取对应的方法和属性,jni引入了Sign(签名),具体如下:
获取到java属性的ID后,就可获取和修改java的属性了,非静态属性可调用
Set/GetIntFieldSet/GetBooleanFieldSet/GetDoubleField
Set/GetFloatField
Set/GetLongField
Set/GetShortField
Set/GetObjectField-----------对应数组等
静态属性可调用
Set/GetStaticIntFieldSet/GetStaticBooleanFieldSet/GetStaticDoubleField
Set/GetStaticFloatField
Set/GetStaticLongField
Set/GetStaticShortField
Set/GetStaticObjectField
下面举实例
1.调用java属性
java代码如下,在本地方法sayhello里修改其属性score
package com.example; public class jni_test { //在本地方法sayHello里修改score的值 public native void sayHello(); public float score=99.9f; static{ System.loadLibrary("NativeCode"); } public static void main(String[] args) { jni_test temp=new jni_test(); temp.sayHello(); //输出temp的score属性的值 System.out.println("score: "+temp.score); } }
c++本地方法实现的代码:
#include"com_example_jni_test.h" #include<iostream> using namespace std; JNIEXPORT void JNICALL Java_com_example_jni_1test_sayHello(JNIEnv * evn, jobject obj) { //获取java的Class--sayHello方法是非静态方法,所以此时obj是调用这个函数的实例,即java中的实例temp jclass my_class=evn->GetObjectClass(obj); //jclass my_class=evn->FindClass("com/example/jni_test");也可以获取Class //获取java的score属性的FieldID jfieldID score_id=evn->GetFieldID(my_class,"score","F");//(类,属性名.签名) //根据FieldID获取属性 jfloat score=evn->GetFloatField(obj,score_id);//(实例对象,属性ID) //修改java的temp的score的值 evn->SetFloatField(obj,score_id,88.8); }
编译生成dll加入PATH即可.
运行结果为:
至此,成功获取java对象的属性并修改其属性的值
2.调用java方法
在本地方法里调用Max_num,输出最大值
java代码:
package com.example; public class jni_test { //在本地方法sayHello里调用Max_num方法 public native void sayHello(); //返回最大值 public void Max_num(int ok,int ok1) { if(ok>ok1) System.out.println("最大值是: "+ok); else System.out.println("最大值是: "+ok1); } static{ System.loadLibrary("NativeCode"); } public static void main(String[] args) { jni_test temp=new jni_test(); temp.sayHello();//输出最大值 } }
本地方法C++实现
#include"com_example_jni_test.h" #include<iostream> using namespace std; JNIEXPORT void JNICALL Java_com_example_jni_1test_sayHello(JNIEnv * evn, jobject obj) { //获取java的Class--sayHello方法是非静态方法,所以此时obj是调用这个函数的实例,即java中的实例temp jclass my_class=evn->GetObjectClass(obj); //jclass my_class=evn->FindClass("com/example/jni_test");也可以获取Class //获取java的Max_num方法的ID jmethodID max_id=evn->GetMethodID(my_class,"Max_num","(II)V");//(类,属性名.签名) //调用Max_num方法--Call<type>Method--type函数返回值 evn->CallVoidMethod(obj,max_id,100,123);//(对象,方法ID,参数...) }
运行结果:
相关推荐
本知识点详细介绍了如何在C/C++代码中调用Java中的属性和方法。 首先,JNI使用时需注意几个关键点,包括Java与本地方法的命名映射、JVM类型签名以及如何处理基本数据类型与对象类型。JNI方法的命名规则为“Java_包...
本篇文档《JNI本地方法访问Java端的属性和方法共9页》将深入探讨如何通过JNI来访问和操作Java对象的属性以及调用Java方法。 首先,了解JNI的基本概念是至关重要的。JNI提供了一组API,使得本地(非Java)代码可以与...
- JNI方法通常在JNI线程中执行,跨线程操作Java对象需谨慎,可能需要使用`JNIEnv`的同步原语(如`MonitorEnter`和`MonitorExit`)。 在`TESTJNI.zip`的示例中,应该包含了完整的代码和步骤,展示了如何在C++中实现...
1. **定义JNI函数**:在Java或Kotlin中声明native方法,并使用`JNIEXPORT`和`JNICALL`宏定义函数签名。例如,在Java中: ```java public native void callNativeFunction(); ``` 2. **生成JNI头文件**:使用`...
通过 JNI 提供的 `FindClass` 和 `GetMethodID` 函数,你可以找到并获取要调用的 Java 类和方法。接着,使用 `CallXXXMethod` 系列函数(如 `CallVoidMethod`, `CallIntMethod` 等)执行实际的函数调用。 5. **...
为了克服这一限制,开发者通常会利用JNI(Java Native Interface)技术,将Java代码与本地(操作系统特定)代码集成,以便访问操作系统底层的功能。在这个场景中,我们想要读取硬盘的序列号,这是一项需要操作系统...
这种方法确保了即使Java类和方法名发生改变,也能正确找到对应的本地实现。 **本地方法参数处理:** 当Java方法调用本地方法时,JNI会负责将Java类型的参数转换成C/C++类型。同样,在返回值方面,JNI也会进行相应...
这些属性可以通过提供的getter和setter方法进行访问和修改。 ##### 5. `process.cpp`详解 本地方法的实现发生在`process.cpp`文件中,使用了Windows API函数,具体如下: - **`Java_systemProcess_processHandle`**...
在函数中,我们可以使用JNI接口访问Java对象的属性和方法,如获取或设置字段值,调用其他Java方法等。 例如,C++代码可能如下: ```cpp #include "MyJavaClass.h" JNIEXPORT void JNICALL Java_MyJavaClass_...
总之,NDK开发中C语言调用Java方法和获取属性是通过JNI接口完成的,这涉及到对JNI规范的理解,包括函数签名、方法和字段ID的获取,以及调用和访问的方法。正确使用这些机制,可以有效地在本地代码和Java代码之间交互...
3. **对象交互**:JNI允许访问和操作Java对象,包括调用对象的方法和访问成员变量。实例可能涉及如何传递Java对象到本地代码,然后在本地代码中调用其方法或修改其属性。 四、注意事项 - **内存管理**:JNI中的内存...
Java 本地接口(Java Native Interface,JNI)是Java平台的一部分,允许Java代码和其他语言写的代码进行交互。JNI在很多场景下都非常有用,比如当需要利用已有的C/C++库、加速计算密集型任务或者访问操作系统特定...
### JNI攻略之十——操作Java虚拟机 #### 一、启动Java虚拟机的过程与实现 在C或C++中启动Java虚拟机是一项较为高级的技术应用,通常被用于那些需要跨语言交互或者集成Java代码到非Java应用程序中的场景。本文档将...
例如,假设我们有一个自定义的Java类`MyCustomObject`,它有若干属性和方法: ```java public class MyCustomObject { private int id; private String name; // 构造函数、getter、setter、其他方法... } ``` ...
- 定义新的类和方法。 - 处理Java对象和数组。 #### 五、Eclipse + CDT + MinGW 进行Java调用C/C++ - **安装Eclipse 3.2。** - **安装MinGW:** - 下载并安装。 - 设置环境变量。 - **安装CDT插件:** - 下载...
这个过程需要用到JNIEnv指针,它是Java方法调用的环境接口,通过JNIEnv可以找到Java对象和方法,并执行它们。 `xxJNI_ch04_aa_Advanced_ok.pdf`和`xxJNI_ch04_bb_Advanced_ok.pdf`可能包含了JNI的高级话题,比如多...
Java Native Interface(JNI)是Java平台的标准接口,它允许Java代码和其他语言写的代码进行交互。在eclipse下实现Java JNI,主要是为了调用C或C++编写的本地库,这在处理性能敏感的代码或者利用现有C/C++库时非常...
在`media_jni`中,JNI接口被用来在Java层和C/C++层之间建立桥梁,处理媒体相关的低级操作。 2. **AudioTrack**: `android_media_AudioTrack.cpp`是AudioTrack类的JNI实现。AudioTrack是Android API中的一个类,...
1. **创建、检查及更新Java对象**:通过JNI,开发者可以在C/C++环境中创建Java对象,对其进行属性读写等操作。 2. **调用Java和非Java程序所编写的方法**:包括调用win32 API等。 3. **捕获和抛出“异常”**:实现了...