文档章节

读书笔记之inside JVM(2)

村长杨京京
 村长杨京京
发布于 2014/09/03 09:36
字数 1289
阅读 22
收藏 1

JNI——手工编译HelloJNI

原创作品,允许转载,转载时请务必以超链接形式标明文章原始出处、作者信息和本声明。否则将追究法律责任。http://blog.csdn.net/taotaoyouarebaby/article/details/8747580


介绍


JVM封装了各种操作系统实际的差异性的同时,提供了JNI技术,它是一种双向的接口,使得开发者可以通过Java代码调用到各种native的 库,反之亦然。所以JNI(Java Native Interface)能作为Java语言的一部分,她能够作为粘合剂将Java应用和其他本地应用(C/C++,Delphi)集合在一起.

下图就很好的描述了JNIJava应用中的地位和角色:


作为一个双向的接口,JNI能支持两种native代码:native libraries native applications.

(1)你能使用JNI去写一些native methods去允许Java Applications能呼叫native libraries中的函数,native methods的具体实现是可能C,C++或者Delphi

(2)JNI也支持嵌入一个JVM实现到一个本地应用程序中去,去执行那些用Java语言编写的的模块.比如,一个C++编写的浏览器利用内嵌的JVM去执行下载到本地的applet.

实现JNI-Java invoke Native Library的一般步骤如下:

1) 完成Java代码,编写好Java调用类

2)编译你的Java

3)javah生成编译好的class文件对应的C/C++ 函数的头文件

4) 实现头文件中的函数原型,编写native代码

5) native代码编译打包成DLL(win32)或共享库(Linux)

6)将你的Java代码跑起来


手工编译HelloJNI


环境与工具:


win7 x64

jdk1.7.0

vs 2012 compiler for x64

当前目录:E:\programming\practice\java\JNI


编写java代码


//HelloJNI.java

package edu.zt.jni;

public class HelloJNI

{

public native void sayHello();

public static void main(String[] args)

{

System.loadLibrary("hellojni");

new HelloJNI().sayHello();

}

}

编译HelloJNI.java

javac -d . HelloJNI.java


导出C/C++函数头文件


javah edu.zt.jni.HelloJNI

得到edu_zt_jni_HelloJNI.h

#include <jni.h>

#ifndef _Included_edu_zt_jni_HelloJNI

#define _Included_edu_zt_jni_HelloJNI

#ifdef __cplusplus

extern "C" {

#endif

JNIEXPORT void JNICALL Java_edu_zt_jni_HelloJNI_sayHello

(JNIEnv *, jobject);

#ifdef __cplusplus

}

#endif

#endif

注意到上面的头文件中包含了一个外部头文件jni.h,该头文件可以从%jdk%\include\中找到。但是在jni.h中还包含了jni_md.h文件,此文件位于%jdk%\include\win32中。

于是将jni.hjni_md.h文件复制到当前目录,并将edu_zt_jni_HelloJNI.h文件中的

#include <jni.h> 改为 #include jni.h

注:如果不想每次都这么麻烦呢,可以将jni.h和jni_md.h文件所在目录添加到INCLUDE环境变量中(没有则新建)。这样就无需拷贝也无需进行上面的修改。但是,每修改了环境变量都要重启一次命令行。才可以应用更改。


编写native代码

//HelloJNI.c

#include <stdio.h>

#include "edu_scu_jni_HelloJNI.h"

JNIEXPORT void JNICALL

Java_edu_scu_jni_HelloJNI_sayHello(JNIEnv * env, jobject obj)

{

printf("Hello JNI!");

}


编译native代码为DLL


因为本机使用的是64位的java VM,所以需要编译为64位的程序,因为也就需要为64位程序设计的编译器。在此,我使用vs201264位编译器进行编译。

找到:开始菜单->Microsoft Visual Studio 2012->Visual studio tools->VS2012 x64 Cross Tools Command Prompt。点击即可打开为编译64位程序配置好的命令行(主要是设置了一些PATHLIB)。

该命令行具体配置了什么内容可以查看vcvarsall.bat文件。

查看VS2012 x64 Cross Tools Command Prompt快捷方式的属性,目标位置有以下内容:

%comspec% /k ""D:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat"" x86_amd64

转到当前工作目录,编译HelloJNI

cl /c HelloJNI.c

此外要生成DLL文件还需要一个.def文件。

//hellojni.def

LIBRARY HelloJNI

EXPORTS

Java_edu_scu_jni_HelloJNI_sayHello @1

连接HelloJNI生成DLL

link /def:HelloJNI.def /dll HelloJNI.obj

可能会出现如下警告

warning LNK4197: export xx specified multiple times; using first specification

但无关紧要。

至此hellojni.dll文件成功生成!


运行


java edu.zt.jni.HelloJNI

出现

Hello JNI!

至此方为成功!


JNI的优缺点

JNI 编程在软件开发中运用广泛,其优势可以归结为以下几点:

1 利用 native code 的平台相关性,在平台相关的编程中彰显优势。

2 对 native code 的代码重用。

3 native code 底层操作,更加高效。

然而任何事物都具有两面性,JNI 编程也同样如此。程序员在使用 JNI 时应当认识到 JNI 编程中如下的几点弊端,扬长避短,才可以写出更加完善、高性能的代码:

1 从 Java 环境到 native code 的上下文切换耗时、低效。

2 JNI 编程,如果操作不当,可能引起 Java 虚拟机的崩溃。

3 JNI 编程,如果操作不当,可能引起内存泄漏。

4 使应用失去了跨平台的能力,如果要移植到别的平台就需要重写native代码。


HelloJNI文件列表



参考


http://blog.csdn.net/todototry/article/details/1638849 如何手工编写动态链接库(windows dll)

http://blog.csdn.net/ididcan/article/details/6828982 JNI简单实现Java调用C++/CHelloWorld

传智播客_王择佑_JNI第一讲

http://www.ibm.com/developerworks/cn/java/j-lo-jnileak/index.html?ca=drs- 在 JNI 编程中避免内存泄漏

问题:

jni.h的实现文件(dll库)在哪里,这个我还没有整明白。

本文转载自:http://blog.csdn.net/taotaoyouarebaby/article/details/8747580

村长杨京京
粉丝 162
博文 878
码字总数 907544
作品 0
杭州
程序员
私信 提问
读书笔记之《Java并发编程的艺术》-并发编程容器和框架(重要)

读书笔记部分内容来源书出版书,版权归本书作者,如有错误,请指正。 欢迎star、fork,读书笔记系列会同步更新 git https://github.com/xuminwlt/j360-jdk module j360-jdk-thread/me.j360....

Hi徐敏
2015/11/11
743
1
读书笔记之《Java并发编程的艺术》-并发编程基础

读书笔记部分内容来源书出版书,版权归本书作者,如有错误,请指正。 欢迎star、fork,读书笔记系列会同步更新 git https://github.com/xuminwlt/j360-jdk module j360-jdk-thread/me.j360....

Hi徐敏
2015/11/11
4K
8
Android--面试中遇到的问题总结(三)

《Android 开发工程师面试指南 LearningNotes 》,作者是陶程,由梁观全贡献部分。大家可以去知乎关注这两位用心的少年。这份指南包含了大部分Android开发的基础、进阶知识,不仅可以帮助准备...

sealin
2017/02/22
0
0
读书笔记之《Java并发编程的艺术》-线程池和Executor的子孙们

读书笔记部分内容来源书出版书,版权归本书作者,如有错误,请指正。 欢迎star、fork,读书笔记系列会同步更新 git https://github.com/xuminwlt/j360-jdk module j360-jdk-thread/me.j360....

Hi徐敏
2015/11/11
772
1
用思维导图来学java虚拟机,轻松易懂!

说明 本篇文章是对周志明的《深入理解Java虚拟机》的读书笔记,思维导图使用Mindjet MindManager。曾经看到过这样一句话: 关于教育,有一个经典的定义是:把在学校里学到的东西全部忘掉,最...

小刀爱编程
2018/10/12
181
0

没有更多内容

加载失败,请刷新页面

加载更多

Shell学习成果之一键自动安装Mysql8.0

实验环境 系统:CentOS7.7.1908 MySql:mysql-8.0.18-el7-x86_64.tar.gz 一键安装脚本如下(可直接复制粘贴为shell脚本,与MySQL安装包放到同一目录;如果没有下载安装包就取消第26行的注释会...

网络小虾米
31分钟前
4
0
X-MSG-IM-系统依赖的第三方library编译

X-MSG-IM系统核心网元编译时依赖较多第三方库, 较为繁琐. 这是为了在部署时更方便, 更少地依赖宿主系统环境. 除非你知道自己在做什么, 否则不要变更这些库的版本. zlib-1.2.11编译 wget htt...

x-msg-im
今天
6
0
电磁兼容谐波电流测试怎么做?看完这篇文章90%的人都能明白

在正式学习谐波电流测试之前,先给大家分享一个故事: 1807年时年39岁的法国数学家傅里叶于法国科学学会上展示了一篇论文"热的传播"(Mémoire sur la propagation de la chaleur),论文中有个...

demyar
今天
3
0
数据管理必看!Kendo UI for jQuery过滤器的全球化

Kendo UI for jQuery最新试用版下载 Kendo UI目前最新提供Kendo UI for jQuery、Kendo UI for Angular、Kendo UI Support for React和Kendo UI Support for Vue四个控件。Kendo UI for jQue......

FILA6666
今天
4
0
ES6基础入门之let、const

作者 | Jeskson 来源 | 达达前端小酒馆 01 首先呢?欢迎大家来学习ES6入门基础let,const的基础知识内容。初始ECMA Script6。 ESMAScript与JavaScript的关系: ES是JS的标准(ES是对ECMAScr...

达达前端小酒馆
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部