c++工程与java的互相调用
来源:互联网 发布:淘宝网中老年运动套装 编辑:程序博客网 时间:2024/06/06 04:03
JNI简介
JNI:Java Native Interface,是Java语言提供的一种通用接口,用于Java代码与本地化代码的交互。所谓本地化代码是指直接编译成的与机器相关的二进制代码,而非Java字节码之类的中间代码。Windows下面的可执行文件,DLL等,Linux下面的可执行文件和SO文件等,都是二进制代码。
JNI允许Java语言编写的程序与其他语言编写的程序库(DLL, SO)或可执行文件进行互操作,包括汇编、C、C++。JNI产生的原因在于以下几种需求:
(1)、你的应用程序需要使用系统相关的功能,而Java代码不支持或是难以办到。这个比较典型的是实现托盘图标,有几种现成的方案都是用的JNI做的,名字好像是叫做TrayIcon和StayOnTop。当然啦,如果是用的Java1.6,那就要另当别论了。
(2)、已有其他语言写好的类库或程序,希望Java程序可以使用它们。
(3)、出于更高的性能要求,希望使用汇编或是C/C++语言来实现部分功能。
下图出自JNI Tutorial,展示了JNI的地位:
以上参考自http://blog.csdn.net/chenjin_zhong/article/details/5870305
一.C++调用JAVA工程
这部分的内容详见我上传的资源文档《c++调用java工程总结》,在此不再赘述!
二. JAVA调用C++
主要分为以下几个步骤:
1.在java类中编写native方法
这一步很简单,就是在java类中写一个带native关键字的函数,比如:public native int buildTripleToIndexBin(String strPredFile1, String strPredFile2,
String strUriFile, String strTripleFile, String strOutTripleBin, String strOutUriBin);
2.编译java工程生成class文件
这一步也很简单,特别是如果用的eclipse开发环境,就不必去命令行窗口下运行javac命令了,只需要“debug”或者“run”就可以得到对应的class文件。
3.利用javah命令处理类文件,生成c++头文件
这一步非常关键,也非常容易出错。下面用个例子说明一下:
我的java工程所在目录:E:\SVN\src\source\Video_Ont_Build
这是eclipse自动管理的工程目录,需要说明的只有src目录和bin目录。其中src目录下存放的所有的包以及包下面的java文件,每个包及其下面的文件都是一个目录;src目录下存放的所有的包以及根据包下面的java文件生成的对应的class文件,每个包及其下面的class文件都是一个目录。我们需要做的是切换到bin目录下进行反编译
生成对应的c++头文件。
好了,说明到此为止,现在打开命令行,切换到相应的目录下:
然后执行命令:
javah -classpath .;D:\eclipse_install_lib\apache-jena-2.7.4\lib\jena-core-2.7.4.jar VideoOntology.VideoOntBuilder
注意一下-classpath参数,表示从中加载类的路径,多个路径中间用;隔开,并且也要设置引用的外部jar包的路径。
该命令运行完之后就可以在bin目录下得到c++头文件,我这里是VideoOntology_VideoOntBuilder.h。
4.使用C++实现native方法,编译成动态库dll文件
首先到java安装目录下的jdk目录下的include目录下拷贝jni.h和win32/jni_md.h到c++工程目录下,并且将上一步生成的VideoOntology_VideoOntBuilder.h也拷贝到c++工程目录下,如图:
然后开始实现c++工程中的本地方法:
实现完之后将对应的c++工程编译成dll文件,并放到jdk安装目录的bin目录下,比如:D:\ProgramSoftware\java7-x64\jdk\bin。或者放到C:\Windows\System32目录下也行,两个都可以。
这里比较让我困惑的是,我在函数的开头调用GetStringUTFChars函数得到转换的c++字符串,然后在函数的最后调用ReleaseStringUTFChars释放这部分的内存,在程序运行的的时候竟然报错:
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# E:\SVN\src\source\Video_Ont_Build\hs_err_pid4876.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.sun.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
然后我把ReleaseStringUTFChars这部分行去掉,竟然不报错,非常诡异啊。按理说我一开始申请了字符串的内存,使用完之后释放这部分内存,这应该是正确的使用内存的步骤,不然可能出现内存泄露。但是这里竟然“不让”释放内存,为毛啊,不解中。。。。
5.在java中加载生成的dll文件,调用c++本体方法
在java类下添加代码:
static {
System.loadLibrary("VQAIndex");
}
VQAIndex就是上一步生成的动态库文件,这里不需要写dll,系统会自动添加后缀.dll!!
最后就是在java类中调用本体方法了,并且“run”,等待JAVA程序执行
就会看到java程序开始调用c++代码喽,哈哈!!
- c++工程与java的互相调用
- JNI JAVA与C的互相调用
- C/C++与Java之间的互相调用
- Android Ndk中C与JAVA之间的互相调用
- Java与C互相调用实例详解
- Java与C互相调用实例详解
- TCL与c/c++的互相调用
- TCL与c/c++的互相调用
- lua与C的互相调用
- Lua 脚本语言 与 C的互相调用
- JavaScript与Objective-C的互相调用
- C与C++互相调用的方法
- Js与java的互相调用
- JS 与JAVA 的互相调用
- javascript与java的互相调用
- C与C++互相调用
- c与c++互相调用
- c++与c互相调用
- 取得长度为length的字符串,一个汉字算两个字符
- ArcGis Engine 基本工具 代码意思
- 比较时间的大小
- 生活中难得一见的超猛图
- ListView 滑动删除效果
- c++工程与java的互相调用
- 变态鹦鹉笑话全集
- Struts前端验证
- java 实现 上一周 本周 下一周 切换时获得 星期一 星期日 时间
- Java日期计算
- js将数值格式化成金额形式
- js将金额还原成数值形式
- javascript中处理时间
- plsql 中配置远程数据库连接