JNI之He'llWord

本文介绍了Java Native Interface (JNI) 的应用场景及其实现步骤,通过实例演示如何在Java中调用C/C++代码,并讨论了JNI中的数据类型映射。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[java]  view plain  copy
  1. JNI其实是Java Native Interface的简称,也就是java本地接口。它提供了若干的API实现了和Java和其他语言的通信(主要是C&C++)。也许不少人觉得Java已经足够强大,为什么要需要JNI这种东西呢?我们知道Java是一种平台无关性的语言,平台对于上层的java代码来说是透明的,所以在多数时间我们是不需要JNI的,但是假如你遇到了如下的三种情况之一呢?  

  1. 你的Java代码,需要得到一个文件的属性。但是你找遍了JDK帮助文档也找不到相关的API。
  2. 在本地还有一个别的系统,不过他不是Java语言实现的,这个时候你的老板要求你把两套系统整合到一起。
  3. 你的Java代码中需要用到某种算法,不过算法是用C实现并封装在动态链接库文件(DLL)当中的。

对于上述的三种情况,如果没有JNI的话,那就会变得异常棘手了。

步骤1.新建用eclipse创建一个Java工程,新建一个SyaHelloToCPP,如下

[java]  view plain  copy
  1. package com.fyb.jnitest;  
  2.   
  3. public class SayHelloToCpp {  
  4.       
  5.     public SayHelloToCpp(){  
  6.           
  7.     }  
  8.     public native void sayHello(String name);  
  9. }  

步骤2.在终端进入工程的根目录,输入命令:

javah -classpath   /Users/guiqulai/Documents/cocos3.0_project/TESTP/bin -d bin/class -jnicom.fyb.jnitest.SayHelloToCpp

命令解释:javah是帮助生成地层c/c++头文件的命令。 -classpath指定编译好的java字节码(.class)文件位置.但不包含包对应的路径。注意这里最后是进入"bin"文件夹。如果classpath不正确,会出现"找不到类 ..."的错误

  -d指定生成的头文件保存的位置  -jni 指定完整的包名+类名

注意:在执行javah的时候,要输入完整的包名+类名。否则在以后的测试调用过程中会发生java.lang.UnsatisfiedLinkError这个异常


步骤3.接下来编写 Android.mk,该文件可以直接从NDK的samples下的hello-jni的jni文件下直接靠过来改改就可以了。 

其中只需要该LOCAL_MODULE和LOCAL_SRC_FILES就可以了。
说明:LOCAL_MODULE是描述模块的,用来给java调用的模块名,会生成对应的libSayHelloToCpp.so
LOCAL_SRC_FILES就是源文件,多个文件空格隔开即可。
工程目录下存在一个jni文件夹,把c/c++类文件和android.mk移到jni目录下

打开命令窗口,进入到项目底下,输入$NDK_ROOT/ndk-build命令,即可自动生成libs/armeabi/libtestJni.so文件。

如果报错,指定NDK_PROJECT_PATH,如下面命令。

$NDK_ROOT/ndk-build NDK_PROJECT_PATH=/Users/guiqulai/Documents/cocos3.0_project/TESTP

应该会提示.so文件生成成功


其实在Java代码中,除了对本地方法标注native关键字和加上要加载动态链接库之外,JNI基本上是对上层coder透明的,上层coder调用那些本地方法的时候并不知道这个方法的方法体究竟是在哪里,这个道理就像我们用JDK所提供的API一样。所以在Java中使用JNI还是很简单的,相比之下在C++中调用java,就比前者要复杂的多了。

 

现在来介绍下JNI里的数据类型。在C++里,编译器会很据所处的平台来为一些基本的数据类型来分配长度,因此也就造成了平台不一致性,而这个问题在Java中则不存在,因为有JVM的缘故,所以Java中的基本数据类型在所有平台下得到的都是相同的长度,比如int的宽度永远都是32位。基于这方面的原因,java和c++的基本数据类型就需要实现一些mapping,保持一致性。下面的表可以概括:

 

    Java类型                本地类型                 JNI中定义的别名    
intlongjint
long_int64jlong
bytesigned charjbyte
booleanunsigned charjboolean
charunsigned shortjchar
shortshortjshort
floatfloatjfloat
doubledoublejdouble
Object_jobject*jobject

 

上面的表格是我在网上搜的,放上来给大家对比一下。对于每一种映射的数据类型,JNI的设计者其实已经帮我们取好了相应的别名以方便记忆。如果想了解一些更加细致的信息,可以去看一些jni.h这个头文件,各种数据类型的定义以及别名就被定义在这个文件中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值