java开发第二个jni示例程序(基于linux操作系统)--native层调用java方法
2016-10-10 20:38
806 查看
在java开发第一个jni示例程序(基于linux操作系统)--java层调用native方法一文中向大家介绍了java层如何调用native层的方法,建议大家先读那一篇博客,因为编程的思路没变,重复的我就没写,只写了区别,写文章比变成累多了,这篇文章中我将向大家介绍如何在native层调用java层的方法。
基本步骤依然是:
1、新建java文件(JniMain.java,JniTest.java)
2、编译java文件(JniMain.class,JniTest.class)
3、生成c的头文件(JniMain.h)
4、新建c文件(JniNative.c)
5、生成动态链接库(JniNative.so)
6、运行java程序
有了之前的基础,在这里,native调用java层的方法主要在JniNative.c文件中,其他文件基本没变,大家自行查看,我对JniNative.c进行了详细注释,我直接上代码:
基本步骤依然是:
1、新建java文件(JniMain.java,JniTest.java)
2、编译java文件(JniMain.class,JniTest.class)
3、生成c的头文件(JniMain.h)
4、新建c文件(JniNative.c)
5、生成动态链接库(JniNative.so)
6、运行java程序
有了之前的基础,在这里,native调用java层的方法主要在JniNative.c文件中,其他文件基本没变,大家自行查看,我对JniNative.c进行了详细注释,我直接上代码:
JniMain.java public class JniMain{ static{ System.load("/home/zhangmingbao/user/java/jnitest1/JniNative.so"); } private static int staticIntField = 300; private static native JniTest oncrateobjForJniTest(); public static void main(String[] args) { System.out.println("oncrateobjForJniTest() call native method"); JniTest jniTest = oncrateobjForJniTest(); jniTest.callTest(); } }
JniTest.java public class JniTest{ private int intField; public JniTest(int num) { intField = num; System.out.println("use JniTest constructure:"+intField); } public void callByNative(int num) { System.out.println("JniTest.callByNative function was called:"+num); } public void callTest() { System.out.println("obj of JniTest is called , intField = "+intField); } }
JniMain.h /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class JniMain */ #ifndef _Included_JniMain #define _Included_JniMain #ifdef __cplusplus extern "C" { #endif /* * Class: JniMain * Method: oncrateobjForJniTest * Signature: ()LJniTest; */ JNIEXPORT jobject JNICALL Java_JniMain_oncrateobjForJniTest (JNIEnv *, jclass); #ifdef __cplusplus } #endif #endif
JniNative.c #include "JniMain.h" #include <stdio.h> /*此本地方法在java类中申明是静态的,静态的类可以通过类名直接调用,所以传递的第二个参数是jclass,是指的对类的引用,而在前一篇写jni的博客中因为没有把方法申明为静态的,所以传递的是jobject,即对象的引用*/ JNIEXPORT jobject JNICALL Java_JniMain_oncrateobjForJniTest (JNIEnv *env, jclass clazz) { /*申明一个jclass类类型变量*/ jclass targetClass; /*申明一个jint类型变量(对应java中的int)*/ jint staticIntField; /*申明一个jmethodID类型变量,保存方法的ID*/ jmethodID mid; /*申明一个jfieldID类型变量,保存变量的ID*/ jfieldID fid; /*申明一个jstring类型变量,对应java的String*/ jstring res; /*申明一个jobject类型变量,对应较多,请查看c与java变量类型的对应关系*/ jobject obj; /*获取JniMain.java中的staticIntField变量的ID,clazz是传入的参数,是对JniMain.java的引用,"I"是变量的描述符。代表这是一个int类型的变量,变量描述符或者方法描述符可以通过反编译javap -s -p JniTest查看*/ fid = (*env)->GetStaticFieldID(env,clazz,"staticIntField","I"); /*获取JniMain.java中的staticIntField变量的值,clazz是传入的参数,是对JniMain.java的引用。*/ staticIntField = (*env)->GetStaticIntField(env,clazz,fid); printf("staticIntField =%d\n", staticIntField); printf("%s\n", "12334344444444444"); /*查找JniTest.java类,添加targetClass对JniTest.java的引用*/ targetClass = (*env)->FindClass(env,"JniTest"); /*获取JniTest.java类的构造方法的ID,"<init>"代表构造方法,"(I)V"代表方法描述符,I代表参数为int类型,V代表函数返回值为void*/ mid = (*env)->GetMethodID(env,targetClass,"<init>","(I)V"); /*创建对象,100是构造方法中的参数*/ obj = (*env)->NewObject(env,targetClass,mid,100); /*获取JniTest.java中的callByNative方法*/ mid = (*env)->GetMethodID(env,targetClass,"callByNative","(I)V"); /*调用JniTest.java类的callByNative方法,200是参数*/ (*env)->CallVoidMethod(env,obj,mid,200); fid = /*查找JniTest.java类中intField的ID*/ (*env)->GetFieldID(env,targetClass,"intField","I"); /*为JniTest.java类中intField变量赋值*/ (*env)->SetIntField(env,obj,fid,200); /*返回一个JniTest.java对象*/ return obj; }
Makefile JniNative.so:JniNative.o gcc -I"${JAVA_HOME}/include" -I"${JAVA_HOME}/include/linux" -shared -o JniNative.so JniNative.o JniNative.o:JniNative.c gcc -I"${JAVA_HOME}/include" -I"${JAVA_HOME}/include/linux" -c -fPIC -o JniNative.o JniNative.c
相关文章推荐
- java开发第一个JNI示例程序(基于linux操作系统)--java调用native方法
- java开发第三个JNI示例程序(基于linux操作系统)--Invocation Api实现native层运行java程序
- linux下通过eclipse开发用java调用c程序的方法
- [原创]Android 基于NDK的JNI开发 C调用java和java调用C的进阶教程
- Android-NDK开发之基础--Android JNI实例代码(一)-- 在JNI中执行Java方法--C/C++调用Java
- Linux下基于Java的程序乱码的解决方法
- 关于JNI的使用(实战linux平台下java调用本地c语言方法)
- 1Java程序通过JNI调用本地C++_第一个示例_HelloWorld
- 3Java程序JNI调用C++之修改属性调用方法
- Android 基于NDK的JNI开发 C调用java和java调用C的进阶教程
- Android 基于NDK的JNI开发 C调用java和java调用C的进阶教程
- [原创]Android 基于NDK的JNI开发 C调用java和java调用C的进阶教程
- Android-NDK开发之基础--Android JNI实例代码(一)-- 在JNI中执行Java方法--C/C++调用Java
- Android-NDK开发之基础--Android JNI实例代码(一)-- 在JNI中执行Java方法--C/C++调用Java
- Android NDK 开发(三)JNI 调用Java属性和方法
- #菜鸟之旅#Android Studio开发JNI工程——Native调用Java方法获取IMEI
- linux下java调用.so文件的方法1: JNI
- [JNI]开发之旅(7)JNI函数中调用java对象的方法
- 【Linux】shell调用Java程序main方法通过crontab定时执行
- JAVA通过JNI调用C#dll方法说明(包含示例)