java与c/c++之间的数据交互
    JNI
   
上述两篇文章对jni的讲解比较详细,各有利弊,就文章1来说,开门见山,直接阐述了java和C/C++的交互方式;文章2是一篇百度文库中的内容,则讲的比较详细,从各个方面阐述了jni到底是个怎么一回事,很适合初学者看。

JNI是Java
Native
Interface的缩写,它是java平台的一部分,允许Java代码和其他语言写的代码进行交互。使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的。JNI标准至少要保证本地代码能工作在任何Java
虚拟机环境下。
   
在写这篇文章的时候,虽然技术不怎么好,但却是一个实打实的C++程序员,因此在这篇文章中有关java的内容可能表述的不是那么准确。

说到jni,个人觉得有这么一句话说的比较好:只有当你必须在同一进程中调用本地代码时,再使用JNI。为什么这么说,原因很简单,文章开头已经说过了,为什么要写这么文章,原因更加明确了,项目需要,不使用不行。

废话不多说,接下来我就讲述下我个人使用jni时的一些理解和觉着比较重要的地方,在讲解jni时,我从以下方面讲解:头文件生成、类型转换、java代码通过jni调用C++和C++通过jni调用java,至于java怎么加载jni动态库我就不在文章中描述了,毕竟java不太懂。

头文件生成
   
编写带有native声明的方法的java类,使用javac命令编译所编写的java类,然后使用javah +
java类名生成扩展名为h的头文件
    public
native void displayHelloWorld();//所有native关键词修饰的都是对本地的声明
    JNIEXPORT
void JNICALL
Java_HelloWorld_displayHelloWorld(JNIEnv*,jobject);//生成的jni层头文件,在此详细解释下这个函数声明的意思,JNIEXPORT:导出函数、void:U返回值、JNICALL:jni调用接口、Java:java语言、HelloWorld:方法所述类、displayHelloWorld:方法名称、JNIEnv*指针指向一个函数指针表,在VC中可以直接用"->"操作符访问其中的函数、
jobject 指向在此 Java 代码中实例化的 Java 对象
LocalFunction的一个句柄,相当于this指针
    类型转换
JNI环境变量——JNIEnv*的使用
   
说到类型转换,由于作者在使用jni的过程中,jni方法的参数都是json的字符串类型传递,因此网上传递数组的方式我就不多解释了,反正用的也不多

首先我说下jstring转换为char
*,为了方便使用,我们可以自定义类,把这两个方法分别封装在类的构造函数和析构函数中。
const char* GetStringUTFChars (jstring string,jboolean*
isCopy)
   
返回指向字符串UTF编码的指针,如果不能创建这个字符数组,返回null。这个指针在调用ReleaseStringUTFChar()函数之前一直有效。
参数:string Java字符串对象,isCopy
如果进行拷贝,指向以JNI_TRUE填充的jboolean,否则指向以JNI_FALSE填充的jboolean。

void ReleaseStringUTFChars(jstring str, const char* chars)
   
通知虚拟机本地代码不再需要通过chars访问Java字符串。
    参数:string
Java字符串对象,chars 由GetStringChars返回的指针
    下边是char *
转换为jstring,为了方便起见还是封装成类来使用。
jstring NewStringUTF(const char *utf)
   
返回一个新的Java字符串并将utf内容拷贝入新串,如果不能创建字符串对象,返回null。通常在反值类型为string型时用到。

参数:utf
UTF编码的字符串指针,对于数值型参数,在C/C++中可直接使用void DeleteLocalRef(jstring
str)释放jstring串和本地字符串的关联关系。

java代码通过jni调用C++
   
java写的native方法调用时对应的就调用了jni层的方法,然后我们只需要实现jni的方法时,调用我们自己的C++嗲吗,就实现了java掉C++。

C++通过jni调用java
jmethodID:保存java方法ID的数组,获取方法下文有讲解
CallVoidMethod:JNIEnv
*方法,参数1:jobject对象,由jni层传入,并暂时保存在jni层、参数2:java方法ID、后边一次是被调用方法的参数

JavaVM::AttachCurrentThread:附加到当前线程
JavaVM::DetachCurrentThread:从当前线程脱离

JNIEnv *pEnv;
global_vm->GetEnv((void**)&pEnv, JNI_VERSION_1_6);
bool isAttached = false;
if (pEnv == NULL)
{
int status = global_vm->AttachCurrentThread(&pEnv, NULL);
if (status < )
{
return;
}
isAttached = true;
}
JniString *jsSourceID = new JniString(pEnv, strGroupID.c_str()); pEnv->CallVoidMethod(m_pCallback, m_pMethodId[], jsSourceID->getL(), nRet); delete jsSourceID;
if (isAttached)
global_vm->DetachCurrentThread();

基于以上代码给出如下解释:
JniString:自己封装的类,把char *变量封装成jstring类型变量

jobject m_pCallback = pEnv->NewGlobalRef(pCallback);//pCallback为jObject,由java代码引入,jni层注册到此
jclass m_pClass = (jclass)pEnv->NewGlobalRef( pEnv->GetObjectClass(m_pCallback));
m_pMethodId[] = pEnv->GetMethodID(m_pClass, "OnUpdateGroupSite", "(Ljava/lang/String;I)V");

至此,java和C++的相互调用就基本讲完了,如果有什么不对的地方或者不理解的地方,欢迎大家留言反问!!!

jni c++的更多相关文章

  1. android studio 使用 jni 编译 opencv 完整实例 之 图像边缘检测!从此在andrid中自由使用 图像匹配、识别、检测

    目录: 1,过程感慨: 2,运行环境: 3,准备工作: 4,编译 .so 5,遇到的关键问题及其解决方法 6,实现效果截图. (原创:转载声明出处:http://www.cnblogs.com/lin ...

  2. 【走过巨坑】android studio对于jni调用及运行闪退无法加载库的问题解决方案

    相信很多小伙伴都在android开发中遇到调用jni的各种巨坑,因为我们不得不在很多地方用到第三方库so文件,然而第三方官方通常都只会给出ADT环境下的集成方式,而谷歌亲儿子android studi ...

  3. Android游戏开发实践(1)之NDK与JNI开发03

    Android游戏开发实践(1)之NDK与JNI开发03 前面已经分享了两篇有关Android平台NDK与JNI开发相关的内容.以下列举前面两篇的链接地址,感兴趣的可以再回顾下.那么,这篇继续这个小专 ...

  4. JNI 备注

    本文记录一个基础的JNI例子及过程中遇到的问题解决. 1.定义一个JAVA类如下: package jnidemo01; public class JniHello { public native v ...

  5. Android游戏开发实践(1)之NDK与JNI开发01

    Android游戏开发实践(1)之NDK与JNI开发01 NDK是Native Developement Kit的缩写,顾名思义,NDK是Google提供的一套原生Java代码与本地C/C++代码&q ...

  6. Android游戏开发实践(1)之NDK与JNI开发02

    Android游戏开发实践(1)之NDK与JNI开发02 承接上篇Android游戏开发实践(1)之NDK与JNI开发01分享完JNI的基础和简要开发流程之后,再来分享下在Android环境下的JNI ...

  7. 关于jni编译32位、64位动态库(Android.mk和Application.mk文件)

    最近新项目需要编译64位的动态库,这里记录如何配置. 在jni目录下加入Android.mk和Application.mk文件. Application.mk APP_ABI := armeabi a ...

  8. android JNI 调用NDK方法

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

  9. jni操作jobject

    一. 注册JNI函数 1.         静态方法 一般使用javah进行编译,生成很长的文件名和函数名字,这个书写不方便,影响运行效率. 2.         动态注册 使用JNINativeMe ...

  10. JNI开发的常见错误

    1. 写错了load的library java.lang.UnsatisfiedLinkError: Couldn't load hell0: findLibrary returned null 2. ...

随机推荐

  1. 使用loadrunner录制手机脚本

    1.安装loadrunner补丁包4: 2.安装了loadrunner的PC端上面创建WiFi热点,将手机接入该WiFi: 3.然后打开loadrunner,选择录制协议为手机的协议: 4.弹窗中选择 ...

  2. .Karma+Jasmine+karma-coverage

    单元测试(模块测试)是开发者编写的一小段代码,用于检验被测代码的一个很小的.很明确的功能是否正确.通常而言,一个单元测试是用于判断某个特定条件(或者场景)下某个特定函数的行为. Karma是一个基于N ...

  3. Laravel修改验证提示信息为中文

    1.覆盖提示信息: 打开resource/lang/en/validation.php注释掉英文提示信息 $ sudo vim resource/lang/en/validation.php 将下面的 ...

  4. VSTO 获取sheet单元格行列数

    Public Sub Igor() Dim Dtsheet As Excel.Worksheet Dim TotalC As Long '原始数据范围列 Dim TotalR As Long '原始数 ...

  5. angularjs和ajax的结合使用 (三)

    转眼九月份了,忙忙碌碌 发现今年还没开过张,写一篇吧. 15年在空闲时就倒腾过angularjs那玩意儿 ,觉得还是挺好的,李金龙那厚厚的一本书,只不过没有系统化应用.最主要的是原来有一个东西没有用到 ...

  6. JavaScript中实现小数点后保留2位

    在项目中有时候会遇到要求输入的数字是整数或者小数点后绑定2位小数,因此可以用.toFixed(2)方法 下面是关于toFixed()方法的demo: <input type="numb ...

  7. 201771010126 王燕《面向对象程序设计(java)》第十八周学习总结

    实验十八  总复习 实验时间 2018-12-30 1.实验目的与要求 (1) 综合掌握java基本程序结构: (2) 综合掌握java面向对象程序设计特点: (3) 综合掌握java GUI 程序设 ...

  8. [LeetCode] Bus Routes 公交线路

    We have a list of bus routes. Each routes[i] is a bus route that the i-th bus repeats forever. For e ...

  9. 查看 FormData 中已存在的值

    var formData = new FormData(); formData.append('name','bob'); formData.append('sex','male'); formDat ...

  10. pyhton 监听文件输入实例

    def tail(filename): f = open(filename,encoding='utf-8') while True: line = f.readline() if line.stri ...