一种让Java调用其他语言的技术。
本博文将会介绍JNI 调用C++的技术。
博文的结尾有关于此教程的所有代码的免积分下载。
HelloWorld.java:
package com.hello; public class HelloWorld { public native void hello(String name); public HelloWorld(){ } static { System.loadLibrary( "HelloWorld" ); } }
注意下,如果我们用JNI编出的文件叫: HelloWorld.dll ,那么System.loadLibrary("HelloWorld"),不用加“.dll”。
TestHelloWorld.java:
package com.hello; public class TestHelloWorld { public static void main(String[] args) { HelloWorld helloWorld = new HelloWorld(); helloWorld.hello("emaster"); } }
编译一下,生成两个class文件。
在开始之前,我推荐大家用VC++6.0,而不是CodeBlocks来编写C++方面的代码!
理由如下:
这是CodeBlocks生成的DLL的导出函数:
_Z44Java_com_regMonitor_RegMonitor_jniRegMonitorP7JNIEnv_P8_jobject@8
_Java_com_regMonitor_RegMonitor_jniRegMonitor@8
导出函数多一些东西之后,会导致我们在Java中找不到对应的函数。
哎,也可能是我 CB没有调整好编译命令吧。总之我在VC下成功了。
Ps:
DLL查看导出函数器,免积分下载
我的工作目录如下:
D:\pub\workspace\JNIHelloWorld\src\com\hello 的目录 2014-05-14 18:04 <DIR> . 2014-05-14 18:04 <DIR> .. 2014-05-14 18:04 218 HelloWorld.java 2014-05-14 18:04 207 TestHelloWorld.java
请注意我生成头文件的目录和命令:
D:\pub\workspace\JNIHelloWorld\bin>javah com.hello.HelloWorld D:\pub\workspace\JNIHelloWorld\bin>dir 2014-05-14 18:21 <DIR> . 2014-05-14 18:21 <DIR> .. 2014-05-14 18:04 <DIR> com 2014-05-14 18:21 475 com_hello_HelloWorld.h看到没有,生成了一个头文件:com_hello_HelloWorld.h。
如果目录不对,很可能报错如下:
错误:无法访问 HelloWorld 错误的类文件: D:\pub\workspace\JNIHelloWorld\bin\com\hello\HelloWorld.class 类文件包含错误的类: com.hello.HelloWorld 请删除该文件或确保该文件位于正确的类路径子目录中。 com.sun.tools.javac.util.Abort at com.sun.tools.javac.comp.Check.completionError(Check.java:162) at com.sun.tools.javadoc.DocEnv.loadClass(DocEnv.java:147) at com.sun.tools.javadoc.RootDocImpl.<init>(RootDocImpl.java:77) at com.sun.tools.javadoc.JavadocTool.getRootDocImpl(JavadocTool.java:159 ) at com.sun.tools.javadoc.Start.parseAndExecute(Start.java:330) at com.sun.tools.javadoc.Start.begin(Start.java:128) at com.sun.tools.javadoc.Main.execute(Main.java:66) at com.sun.tools.javah.Main.main(Main.java:147) javadoc: 错误 - 致命错误 2 错误
VC新建项目,选择Win32 Dynamic-Link Library项目(生成DLL的),默认即可。
我的项目名字为:JNIHelloWorld。
把第4步的头文件:com_hello_HelloWorld.h 放到VC中。
修改下输出DLL的名字:VC菜单 -> 工程 -> 设置 -> 连接 -> 输出文件名 这一栏,改成:Debug/HelloWorld.dll
这样子就和Java代码中的dll名字一样了,其实可以手动F2修改的,这里设置后就不能每次都去修改了,懒人。
把HelloWorld.dll放到Java项目的根目录下,我这里是根目录是:
D:\pub\workspace\JNIHelloWorld所以该dll的路径是:
D:\pub\workspace\JNIHelloWorld\HelloWorld.dll
配置jni头文件,不然C++会报错找不到该头文件:
就是到jdk的安装目录下include下把以下相应的文件,复制到vc目录下的include文件夹下:
\jdk\include\jni.h \jdk\include\win32\jawt_md.h \jdk\include\win32\jni_md.h
D:\Program Files\Microsoft Visual Studio\VC98\Include你们可以根据自己的安装位置自行确定。
代码如下:
com_hello_HelloWorld.h:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_hello_HelloWorld */ #ifndef _Included_com_hello_HelloWorld #define _Included_com_hello_HelloWorld #ifdef __cplusplus extern "C" { #endif /* * Class: com_hello_HelloWorld * Method: hello * Signature: (Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_com_hello_HelloWorld_hello (JNIEnv *, jobject, jstring); #ifdef __cplusplus } #endif #endif
JNIHelloWorld.cpp:
// JNIHelloWorld.cpp : Defines the entry point for the DLL application. // #include "stdafx.h" #include "com_hello_HelloWorld.h" BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; } JNIEXPORT void JNICALL Java_com_hello_HelloWorld_hello (JNIEnv *, jobject, jstring) { printf("I am in C++!\n"); return; }
可以看到,我们在Java中,调用C++的方法成功!
至此,一个完整的HelloWorld版本的JNI过程,就完成了。
emaster 关注信息安全的胖子
欢迎转载,转载请注明地址:http://blog.csdn.net/emaste_r/article/details/25820477