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. python打包工具 cx_Freeze介绍

    原理 Python 脚本在装有 Python 的系统中可以直接双击运行,但绝大多数普通用户并没有配置此类环境,而编译为可执行二进制文件后,用户无需预先安装 Python 及依赖库即可像运行普通程序一样 ...

  2. 《团队作业》五小福团队作业--UNO-- LandingDay--降落

    <团队作业>五小福团队作业--UNO-- LandingDay--降落 写在前面 几周的飞行之后,降落之日也如期而至了.在2018年12月19日我们顺利地完成了项目的总结汇报.但是,短暂的 ...

  3. 彻底卸载MySQL服务

    前言 由于安装某个项目的执行文件,提示要卸载MySQL以便它自身MySQL安装,然后我禁用了MYSQL服务,再把这个文件夹删除后,发现还是提示请卸载MYSQL服务. ----------------- ...

  4. Spring系列__02IOC模块简介

    Spring的两大核心功能就是IOC和AOP,这篇文章主要介绍IOC. 简单来说,在面向对象思想下,A类中有一个B类的属性, 那么我们在创建A类时往往需要同时创建一个B类的对象,以便A类对其进行调用. ...

  5. BZOJ 4455

    树的点到图的点是双射 枚举哪些点可以映射到 然后dp容斥 复杂度 $2^n*n^3$ #include<bits/stdc++.h> using namespace std; #defin ...

  6. JS的常用属性

    JS-------定义:基于事件和对象驱动,并具有安全性能的脚本语言. 引入:<script  type=”text/javascript”>具体js代码</script>   ...

  7. java中class文件与jar文件

    1. JAR 文件包 JAR 文件就是 Java Archive File,顾名思意,它的应用是与 Java 息息相关的,是 Java 的一种文档格式.JAR 文件非常类似 ZIP 文件——准确的说, ...

  8. Python基础之变量作用域

    一.分类: 二.变量名的查找规则: 三.局部变量: 四.全局变量: 五.global语句: 六.nonlocal语句: 七.基础代码: # 全局变量:当前.py文件内部都可访问 g01 = 100 d ...

  9. 解决TCPDF中文乱码,PHP

    /* **主要是这个单词控制 stsongstdlight **/ $this->SetFont('stsongstdlight', 'B', 10);

  10. linux操作命令之搜索命令

    1.文件搜索命令:locate 文件名 在后台数据库中按照文件名搜索,搜素速度更快 /var/lib/mlocate:#locate命令所搜索的后台数据库 updatedb:更新数据库 updated ...