Java通过jni技术支持c、c++调用使用整理

    最近在公司搞终端5.0,说要对c++版本sdk封装一个java版的sdk,可是团队没有搞java的,于是赶鸭子上架,临时学习几天,整了一下;感觉还挺有意思的,于是整理一下;

    为什么要使用java支持对c、c++的调用?

    众所周知Java语言是一门支持跨平台解释型语言;#.java通过javac编译生成生成#.class字节码,运行过程依赖java虚拟机执行字节码生成虚拟机的执行指令,最终通过虚拟机操控所在平台,完成其设计的功能;其优点很明显,支持跨平台;其缺点也很明显,执行效率底,并且不支持平台个性功能;而面对日益满足人们需求的嵌入式设备以及移动设备,由于本身的局限性对效率的要求比较高,故很多底层功能都使用c/c++完成;故java要使用这部分功能,必须以牺牲其跨平台的优势提供支持其他语言调用的接入口,尤其对c、C++,最终提供了Jni技术支持java对其它语言的调用;

     总的来说当出现一些用java语言无法处理的任务时,开发人员就可以利用JNI技术来完成。一般来说下面几种情况需要用到JNI技术:
    一、 开发时,需要调用java语言不支持的依赖于操作系统平台的特性的一些功能。例如:需要调用当前的Unix系统的某个功能,而java不支持这个功能,就需要用到JNI技术来实现。
    二、 开发时,为了整合一些以前的非java语言开发的某些系统。例如,需要用到开发早期实现的一些C或C++语言开发的一些功能或系统,将这些功能整合到当前的系统或新的版本中。
    三、 开发时,为了节省程序的运行时间,必须采用一些低级或中级语言。例如为了创建一个省时的应用,不得不采用汇编语言,然后采用java语言通过JNI技术调用这个低级语言的应用。 据统计jni接口调用比直接使用接口调用,只延迟0.1毫秒,基本不影响效率;

    怎么使用java支持对c、c++的调用?    

    现在以test.java为例,包名为com.yueye,为例;

    一、在test.java中定义Native接口的方法public static native void testjni();

    二、通过javac test.java生成test.class;

    三、通过javah –o test_jni.h –classpath . –jni com.yueye.test生成test_jni.h,其中包含一个方法:

    JNIEXPORT void JNICALL Java_com_yueye_test__(JNIEnv *, jclass, jint);

    这个函数的命名规则是Java_包名_函数名__参数符号

    四、实现Java_com_yueye_test__,生成动态库;

    五、在java中通load或者loadlibrary导入动态库,然后再直接调用native方法;

    附上一个完整的例子:https://files.cnblogs.com/cainiaozhanchi/hello-world.zip

    使用java进行c、c++调用过程问题的总结

    一、导入库失败主要有以下几个方面的原因;

    <1>库以及依赖库是否放在环境变量路径中;

    <2>所有库是否都齐全;

    <3>所有库是否有效;

    二、使用jni技术导入库成功后调用函数直接挂起失败,主要有几个方面原因;

    <1>库中函数命名是否正确;

    <2>函数参数是否正确;

    <3>对应jni函数是否实现;

    <4>jni.h的函数编码是否是使用标准c风格,因为jni技术调用c、c++时,只支持c风格,如果不是c风格函数调用约定就会不一致,导致找不到对应函数;比如3、函数申明在A.h中实现是否在A.cpp中;

    <5>实现函数本身是否有问题;这个可以单步调试进去就可以看出来;

     最后由于对java和jni都是刚刚接触,有整理不对的地方,大家多多指出,然后后续再整理一篇对jni使用的文章以及对jni技术原理理解的文章;

原文地址:https://www.cnblogs.com/cainiaozhanchi/p/4096161.html