JNI开发笔记(一)

C/C++  互相通过的接口,本地的C/C++代码可以调用Java代码
JNI是本地编程接口,NDK快速开发C(C++)动态库,将so和Java应用一起打包成apk
将复杂的逻辑和算法通过本地代码(C/C++)

反汇编.so动态库分析程序的逻辑要复杂
设备提供C接口,而Java不能直接与C进行交互,先在Java层定义发送短信等 native方法,用javah命令将定义Java native接口的class字节码文件生成.h文件,最后用设备的C接口实现java的native方法,编译成 .dll或 .so动态库


打开一个网页,播放视频或打开窗口,C++实现麻烦,用Android应用层提供的API变得容易。Cocos2d-x封装
应用程序需要调用硬件的特定功能,只能通过C/C++封装的JNI接口来提供上层应用
厂商封装好JNI接口,了解JNI与Java通讯原理

C和C++ 复用以前用C/C++写的大量代码

JNI程序受系统环境影响,C/C++编译的模块或代码依赖系统提供的库函数和本地库,不同的操作系统,有自己的本地库和CPU指令集,各个平台的C/C++规范和标准库函数实现方式也有所区别

1.编写声明native方法的Java类
2.Java源代码编程成class字节码文件
3.用javah -jni 生成 .h头文件  -jni表示将class中用native声明的函数
4.用本地代码实现 .h 文件中的函数
5.本地代码编译成动态库 Windows:*.dll Linux:*.so Mac OSx:*.jnilib
6.拷贝动态库至 java.library.path 本地库搜索目录下,运行Java程序

HelloWorld.java

public class HelloWord{
	public calss HelloWorld{
		public static native String sayHello(String name);
		
		public static void main(String[] args){
			String tet = sayHello("yang");
			System.out.println(text);
		}
	}
	
	staic{
		System.loadLibrary("HelloWorld");
	}
}

用本地代码实现 .h 文件中的函数
将C/C++代码编译成本地动态库文件,libHelloWorld.so

一般在类的静态代码块中加载动态库最合适
方式1:只需要动态库名字,不需要lib前缀,也不要.so, .dll, .jnilib后缀
System.loadLibrary("HelloWorld");  java会去java.library.path系统指定目录
方式2:指定动态库的绝对路径,需要前缀后缀
System.load("/User/yangxin/Desktop/libHelloWorld.jnilib");

javah -classpath ./bin//classpath 类搜索路径

javac src/com/HelloWorld.java -d ./bin
-d 表示编译后的class文件放在指定目录下,放在src同级的bin目录

没有将动态库拷贝到本地搜索目录下,执行 java 命令,添加系统属性 java.library.path指定动态库目录  java -Djava.library.path=/Users/yangxin/Desktop
指定系统属性,Linux环境下可设置 LD_LIBRARY_PATH 环境变量指定库的搜索目录

gcc -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -fPIC -shared
-I      包含编译JNI必要的头文件
-fPIC   编译成位置无关独立代码
-shared 编译成到动态库
-o      编译后动态库生成的路径和文件名

JNIEXPORT jstring JNICALL Java_com_study_jnilearn_HelloWorld_sayHello
(JNIEnv *, jclass, jstring)
{
	const char *c_str = NULL;
	char buff[128] = {0};
	c_str = (*env)->GetStringUTFChars(env, j_str, NULL);
	if(c_str == NULL){
		printf();
		return NULL;
	}
	(*env)->ReleaseStringUTFChars(env, j_str, c_str);
	printf("Java Str:%s\n", c_str);
	sprintf(buff, "hello %s", c_str);
	return (*env)->NewStringUTF(env, buff);
}
JVM查找native方法
   调用System.loadLibrary接口 加载实现了native方法的动态库才能正常访问
JVM查找native方法
  按照JNI规范的命名法则
  调用JNI提供的 RegisterNatives 函数,注册到JVM


编译动态库时,用-I包含了两个头文件目录,一个jni.h头文件,一个跨平台头文件目录,用于定义与平台相关的宏,其中用于标识 JNIEXPORT JNICALL
在Windows中编译dll动态库规定,如果动态库中函数要被外部调用,在函数声明中添加 __declspec(dllexport)标识,在Linux/Unix这两个宏可以省略。由于各自的编译器所产生的可执行文件格式不一样。


javah工具生成函数原型的头文件命名规则: Java_类全路径_方法名
JNIEXPORT jstring JNICALL Java_com_study_jnilearn_HelloWorld_sayHello(JNIEnv *, jclass, jstring);
第一个参数:JNIEnv * 定义任意native函数的第一个参数(调用JNI的RegisterNatives函数注册的函数),指向JVM函数表的指针,函数表每一个入口指向一个JNI函数
第二个参数:Java中调用 native 方法的实例或Class对象,如果这个native方法是实例方法,则参数是 jobject,如果是静态方法,则是 jclass
第三个参数:Java对应JNI中的数据类型,Java中String类型对应JNI中的jstring


熟悉命名规则后,不通过javah生成相应的java native方法的函数原型,只需要按照命名规则编写相应的函数原型和实现。
com.study.jni.Utils   计算加法native的add
public native int add(int, int);
JNIEXPORT jint JNICALL Java_com_study_jni_Utils_add(JNIEnv *, jobject, jint,jint);
Java层函数名如果有一个"_",转换成JNI后变成了"_l"
JNIEXPORT void JNICALL Java_android_media_MediaScanner_native_linit
JNIEXPORT void JNICALL Java_android_media_MedaiScanner_processFile


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值