JNI初识,函数规范,基本数据类型,与之对应签名

JNI:Java Native Interface 缩写(Java本地接口)
 JNI是一种本地编程的接口。它允许运行在JAVA虚拟机中的Java代码和其他编程语言相互调用,
比如,c/c++ 写的应用和库之间的相互操作。

作用:

JNI允许我们用其他编程语言来解决用纯粹的java代码不好处理的情况,比如调用一些基于JNI的其他语言的I/O,音视频
相关功能的库,当然也有各种高性能的程序,也用于改造已存在的用其他语言写的程序,供java程序调用。

JNI框架允许Native方法调用Java对象,就像Java程序访问Native对象一样方便。Native方法可以创建Java对象,读取这些
对象,并调用Java对象执行某些方法。当然Native方法也可以读取由Java程序自身创建的对象,并调用这些对象的方法。

缺点:

JNI没有 JVM内存垃圾回收机制,需要使用代码进行显示的释放。
JNI在有些情况下可能带来很呆的开销和性能的损失:
      1.调用 JNI 方法是很笨重的操作,特别是在多次重复调用的情况下。
      2.Java 数组传递给 native 方法时,可能需要拷贝过去,执行完再拷贝回来,开销较大,需要使用多块内存。
      3.Native方法需要使用Java的相关方法属性是,需要类似反射的东西,访问Java对象的属性、方法,非常缓慢容易出错。
      4.使用字符串、对象时非常不灵活,需要单独获取。

一个JNI函数看起来时这样的:

extern "C"  //是为了 C与C++ 混编,按照C语言的方式编译 如果这里是.cpp文件的话,就需要加,如果是.c 文件则不需要
JNIEXPORT void JNICALL  Java_ClassName_MethodName
( JNIEnv  *env, jobject  obj)
{
    
}

大家可以看到这个JNI方法。
这里 JNIEXPORTJNICALL ,定义在jni_md.h头文件中

JNIEXPORT:
在Windows中,定义为__declspec(dllexport)。因为Windows编译dll动态库规定,如果动态库中的函数要被外部调用,
需要在函数声明中添加此标识,表示将该函数导出在外部可以调用。
在 Linux/Unix/Mac os/Android 这种 Like Unix系统中,定义为`__attribute__((visibility ("default")))

JNICALL:
在类Unix中无定义,在windows中定义为: _stdcall,一种函数调用约定
类Unix系统中这两个宏可以省略不加。

然后JNI函数默认被传递一个JNIEnv指针,一个jobject的指针。
JNIEnv: 由Jvm传入与线程相关的变量。定义了JNI系统方法,java交互等方法。
jobject:表示当前调用对象,即 java 中 this ,如果是静态的Native方法,则获得jclass。

自己编写应该是这样的:

这是对应的java代码

native String test(int i,String  j,float k);
extern "C" //因为我这里是 .cpp 文件
JNIEXPORT jstring JNICALL Java_com_example_costomviewtext_ExampleUnitTest_test
(JNIEnv *env, jobject, jint i,jstring j, jfloat k)
{
    //获得c字符串
    //参数1 这个字符串    
    //参数2 是否复制 
    const char* str = env->GetStringUTFChars(j,JNI_FALSE);
    
    //释放掉内存x
    env->ReleaseStringUTFChars(j, str);
    
    //返回字符串
    return env->NewStringUTF(returnStr);
}

jstring 在这里对应的是 Java中的 string 类型,这里代表返回值,可以对应上面Java代码其实也可以看出来。

Java_com_example_costomviewtext_ExampleUnitTest_test 
这个就是JNI的函数命名规范了, Java没什么好说的,咱们看后面的,
com.example.costomviewtext 这个就是我Android项目对应的包名了,然后ExampleUnitTest 是类名 ,
最后test是方法名, 然后这些中间用  _  连接,这边就有个坑了,就说咱们Android中包名命名中可以使用  _ 这个,在这里
如果直接使用,不做处理会有问题,系统会默认处理成连接包名的, 这种情况我们要写成  _1 , 就是在后面加个1,这样系统
就按包名处理了。 
比如 :  com.example.costomview_text 如果我的包名是这个的话, 
 这里我的JNI就得写成 com_example_costomview_1text  这样。

说完这个我们看看 JNI的 数据类型 与Java中的对应关系:

还有基本数据类型对应的签名,这个在后面Native 反射 Java时会有使用,这里不懂也没关系。

 

好了,本篇先写这么多,内容不是很多,主要是先简单了解一下JNI相关的一些简单的东西,这样在后面几篇中就
容易理解了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值