JNI编程入门(-)

最新因工作需要,需要在C++的开发中使用到Java,所以就想到了利用JNI来进行开发,JNI全称Java Native Interface,也就是Java的本地接口,JNI既可以实现Java到本地平台的开发,也可以将本地平台的开发移植到Java上(当然,这里必须要保证二进制的位数一样,因为Java也是程序,JVM也是区分32位版本和64位版本的),下面就简单介绍一下JNI的双向操作,本文章以Java <----> C++的开发为例:

1.在Java中开发,使用C++的库

<1>在Java程序中使用C++,需要在类中声明C++的导出函数。

<2>将相应的动态库加载到Java程序中。

<3>将Java程序中的JNI函数使用javah来生成C/C++的头文件

public class Demo{

public static native int getSum(int x, int y);

public static native int getSub(int x, int y);

public static void main(String[] args){

System.loadLibrary("xxx");

//******这里需要注意的是不需要写动态库后缀

//******windows上默认是.dll,Linux上默认是.so

}

}

下面重点介绍JNI在C++中的开发

2.在C++中开发,使用Java的jar包

在C++中开发使用jar包,首先要确定咱们的C++程序是32位还是64位,因为这个决定了我们的程序应该使用32位

还是64位的jre(java runtime environment),java的运行程序jar包(其实也就是*.class是不区分32位和64位的),

<1>建立Java的虚拟机JVM

<2>将jar包作为JVM运行时的类,启动JVM的时候作为启动参数加入

<3>使用JVM的虚拟环境来查找类、查找类函数、查找域,调用函数,根据构造函数创建类对象

C++中在JVM中使用的几种环境

(1)创建一个类对象

jclass cls = env->FindClass("test/Demo");

jmethodID mid = env->GetMethodID(cls,"<init>","(Ljava/lang/String;)V");

const char szTest[] = "电信";

jstring arg = NewJString(env, szTest);

jobject demo = env->NewObject(cls,mid,arg);

(2)查找一个类

jclass cls = env->FindClass("test/Demo");

这里写类的路径的时候,将完整的类拷贝过来

然后将.改成/即可。例如com.example的类则写成

com/example

(3)查找方法ID

env->GetMethodID(cls,"<init>","(Ljava/lang/String;)V");

特别要注意的是由于这里是构造函数所以使用的是

<init>,其他的类函数则使用相应的函数名称,

特别要注意的是函数的签名,千万最好是从jar包中查看

或者通过javap -s 解析*.class来查看签名,如果手写有时候

容易写错

(4)调用方法

env->CallObjectMethod(demo, mid);

调用的函数根据返回值类型不同而不同

Call###Method,其中###是基本类型或Object

由于String从Object派生,所以String也调用该函数

(5)查找域ID

env->GetStaticFieldID(classID,fieldname,sig)

env->GetBoolFieldID

env->GetObjectFieldID

env->Get###FieldID

这里特别需要注意的有两点

1>如果是静态变量则第一个参数传入类指针,否则传入对象指针

2>除了基础类型以外,其他的均为GetObjectFieldID

(6)获取域值

env->GetStaticObjectField(classPtr, fieldID)

env->GetBooleanField(objectPtr, fieldID)

env->GetObjectField(objectPtr, fieldID);

规则与查找域的前两条一致

(7)调用带参数的构造函数

jclass cls = env->FindClass("test/Demo");

jmethodID mid = env->GetMethodID(cls,"<init>","(Ljava/lang/String;)V");

const char szTest[] = "电信";

jstring arg = NewJString(env, szTest);

jobject demo = env->NewObject(cls,mid,arg);

//验证是否构造成功

mid = env->GetMethodID(cls, "getMessage","()Ljava/lang/String;");

jstring msg = (jstring)env->CallObjectMethod(demo, mid);

cout<<JStringToCString(env, msg);

详情查阅官方文档

http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html#wp4517

创建JVM的Demo

  1. //定义一个函数指针,下面用来指向JVM中的JNI_CreateJavaVM函数
  2. typedef jint (WINAPI *PFunCreateJavaVM)(JavaVM **, void **, void *);
  3. int res;
  4. JavaVMInitArgs vm_args;
  5. JavaVMOption options[3];
  6. JavaVM *jvm;
  7. JNIEnv *env;
  8. /*设置初始化参数*/
  9. //disable JIT,这是JNI文档中的解释,具体意义不是很清楚 ,能取哪些值也不清楚。
  10. //从JNI文档里给的示例代码中搬过来的
  11. options[0].optionString = "-Djava.compiler=NONE";
  12. //设置classpath,如果程序用到了第三方的JAR包,也可以在这里面包含进来
  13. options[1].optionString = "-Djava.class.path=.;c:\\";
  14. //设置显示消息的类型,取值有gc、class和jni,如果一次取多个的话值之间用逗号格开,如-verbose:gc,class
  15. //该参数可以用来观察C++调用JAVA的过程,设置该参数后,程序会在标准输出设备上打印调用的相关信息
  16. options[2].optionString = "-verbose:NONE";
  17. //设置版本号,版本号有JNI_VERSION_1_1,JNI_VERSION_1_2和JNI_VERSION_1_4
  18. //选择一个根你安装的JRE版本最近的版本号即可,不过你的JRE版本一定要等于或者高于指定的版本号
  19. vm_args.version = JNI_VERSION_1_4;
  20. vm_args.nOptions = 3;
  21. vm_args.options = options;
  22. //该参数指定是否忽略非标准的参数,如果填JNI_FLASE,当遇到非标准参数时,JNI_CreateJavaVM会返回JNI_ERR
  23. vm_args.ignoreUnrecognized = JNI_TRUE;
  24. //加载JVM.DLL动态库
  25. HINSTANCE hInstance = ::LoadLibrary("C:\\j2sdk1.4.2_15\\jre\\bin\\client\\jvm.dll");
  26. if (hInstance == NULL)
  27. {
  28. return false;
  29. }
时间: 2024-10-16 07:13:14

JNI编程入门(-)的相关文章

Android jni 编程入门

本文将介绍如何使用eclipse和ndk-build来编写一个基于Android4.4版本的包含有.so动态库的安卓程序. 前提是已经安装和配置好了诸如SDK,NDK等编译环境.下面开始编程! 1 程序逻辑 我们要编写的程序包含两部分:java部分--负责界面和调用JNI native函数:JNI native 部分--负责native函数的具体实现(本文使用C语言). native 函数伪代码如下: ? 1 2 3 4 5 6 7 8 /* funtion: 传入两个整形变量,计算他们之和 r

Android Native jni 编程入门

在某些情况下,java编程已经不能满足我们的需要,比如一个复杂的算法处理,这时候就需要用到jni(java native interface)技术: jni 其实就是java和c/cpp之间进行通信的一个接口规范,java可以调用c/cpp里面的函数,同样,c/cpp也可以调用java类的方法: jni开发工具ndk的安装:在最新的ndk版本中,安装ndk很简单,只需要装ndk的路径配置到系统环境变量中即可:在编译的时候,进入工程根目录:执行命令  ndk-build  即可完成编译: 下面就通

【转贴】-- Android Native jni 编程入门

原帖地址:http://www.cnblogs.com/a284628487/p/4318698.html 在某些情况下,java编程已经不能满足我们的需要,比如一个复杂的算法处理,这时候就需要用到jni(java native interface)技术: jni 其实就是java和c/cpp之间进行通信的一个接口规范,java可以调用c/cpp里面的函数,同样,c/cpp也可以调用java类的方法: jni开发工具ndk的安装:在最新的ndk版本中,安装ndk很简单,只需要装ndk的路径配置到

Android jni本地编程入门

在某些情况下,java编程已经不能满足我们的需要,比如一个复杂的算法处理,这时候就需要用到jni技术: jni : java native interface jni 其实就是java和c/cpp之间进行通信的一个接口规范,java可以调用c/cpp里面的函数,同样,c/cpp也可以调用java类的方法: jni开发工具ndk的安装:在最新的ndk版本中,安装ndk很简单,只需要装ndk的路径配置到系统环境变量中即可:在编译的时候,进入工程根目录:执行命令  ndk-build  即可完成编译:

JNI编程实现(Linux)

JNI是Java Native Interface的缩写,是Java平台的本地调用,从Java1.1就成为了Java标准的一部分,它允许Java代码和其它语言的代码进行互相调用,只要调用约定支持即可,尤其和C/C++的互相调用. 虽然使用Java与本地编译的代码进行交互,会丧失平台的可移植性,但是在特定情况下,这些问题是可以接受的,如: 1.使用一些旧的库 2.需要操作系统交互 3.提高程序的性能 一.jni介绍 Java是通过定义native方法,然后用其它语言实现该方法,最后在Java运行时

《鸡啄米C++编程入门系列》系列技术文章整理收藏

<鸡啄米C++编程入门系列>系列技术文章整理收藏 收藏整理鸡啄米C++编程入门系列文章,供个人和网友学习C++时参考 1鸡啄米:C++编程入门系列之前言 2鸡啄米:C++编程入门系列之一(进制数) 3鸡啄米:C++编程入门系列之二(原码.反码与补码) 4鸡啄米:C++编程入门系列之三(VS2010的使用介绍) 5鸡啄米:C++编程入门系列之四(数据类型) 6鸡啄米:C++编程入门系列之五(运算符和表达式) 7鸡啄米:C++编程入门系列之六(算法的基本控制结构之选择结构) 8鸡啄米:C++编程入

jni ndk 入门

1. Linux环境模拟,下载sygwin 安装,选择devl 和shell -> install sygwin 中的配置ndk环境,进入安装目录c:/cygwin64 etc/profile文件配置ndk的环境 //37行 PATH="/usr/local/bin:/usr/bin:/cygdrive/d/android-ndk-r9d-windows-x86_64/android-ndk-r9d${PATH:+:${PATH}}" 2. 下载ndk 3. 开发,参考于ndk/

【转】Android JNI编程—JNI基础

原文网址:http://www.jianshu.com/p/aba734d5b5cd 最近看到了很多关于热补的开源项目——Depoxed(阿里).AnFix(阿里).DynamicAPK(携程)等,它们都用到了JNI编程,并且JNI编程也贯穿了Android系统,学会JNI编程对于我们学习研究Android源码.Android安全以及Android安全加固等都是有所帮助的.但是对于我们这些写Android应用的,大部分时间都是在使用Java编程,很少使用C/C++编程,对于JNI编程也了解的比较

编程入门指南

前言 如今编程成为了一个越来越重要的「技能」:作为设计师,懂一些编程可能会帮你更好地理解自己的工作内容:作为创业者,技术创始人的身份则会让你的很多工作显得更容易.而作为刚想入门的新手,面对眼前海量的信息,或许根本不知道从哪里开始:入门轻松度过初级材料的学习后,发现学习越来越困难,陡峭的学习曲线又让你望而却步:你知道如何在页面上打印输出一些文本行,但是你不知道何时该进行一个真正的有用的项目:你不清楚自己还有哪些不知道的东西,你甚至搞不清下一步该学什么. 这篇文章的内容对此不仅会有一些方向性的建议,