java JNI 调用c或c++,windows 或 Linux系统

系统 1559 0
由于java程序需要调用C或C++的代码,不得不使用JNI。C的代码在Win32和Linux下都有相同功能的不同实现,就像JDK分几种平台版本(win32,linux,solaris等)。
首先,看一看首先,看一看win32下调用dll文件。
1, 新建HelloWorld.java
1 public class HelloWorld
2 {
3 static
4 {
5 try
6 {
7 // 此处即为本地方法所在链接库名
8 System.loadLibrary( " HelloWorld " );
9 }
catch (UnsatisfiedLinkErrore) {
10 System.err.println( " 不能加载dll文件:\n " + e.toString());
11 }

12 }
// endstatic
13 public native void SayHello(StringstrName);
14
15 }

16
2,编译java文件生成HelloWorld.class文件
3,在命令行下,javah -jni HelloWorld 生成 HelloWorld.h文件
1 /**/ /* DONOTEDITTHISFILE-itismachinegenerated */
2 #include < jni.h >
3 /**/ /* HeaderforclassHelloWorld */
4
5 #ifndef_Included_HelloWorld
6 #define_Included_HelloWorld
7 #ifdef__cplusplus
8 extern"C"{
9 #endif
10 /**/ /*
11 *Class:HelloWorld
12 *Method:SayHello
13 *Signature:(Ljava/lang/String;)
14 */

15 JNIEXPORTvoidJNICALLJava_HelloWorld_SayHello
16 (JNIEnv * ,jobject,jstring);
17
18 #ifdef__cplusplus
19 }
20 #endif
21 #endif
22
4, 编写HelloWorld.cpp
1 #include < windows.h >
2 #include " HelloWorld.h "
3 #include < stdio.h >
4 // 与Hello.h中函数声明相同
5 JNIEXPORT void JNICALLJava_HelloWorld_SayHello(JNIEnv * env,jobjectarg,jstringinstring)
6 {
7 // 从instring字符串取得指向字符串UTF编码的指针
8 const jbyte * str =
9 ( const jbyte * )env -> GetStringUTFChars(instring,JNI_FALSE);
10 printf( " HelloWorld,%s\n " ,str);
11 // 通知虚拟机本地代码不再需要通过str访问Java字符串。
12 env -> ReleaseStringUTFChars(instring,( const char * )str);
13 return ;
14 }

15 int WINAPIDllMain(HINSTANCEhInstance,DWORDfdwReason,PVOIDpvReserved)
16 {
17 return TRUE;
18 }
5,在vc6下新建dll工程HelloWorld,加载HelloWorld.h和HelloWorld.cpp,编译生成HelloWorld.dll文件,最关键的是引用JAVAHOME\include\和JAVAHOME\include\win32的.h文件。
6,设置classpath为dll文件所在路径,新建一个测试类TestHelloWorldDLL.java
1 public class HelloWorld {
2 public static void main(Stringargs[]) {
3 HelloWorldhw = new HelloWorld();
4 hw.SayHello( " Christmas " );
5 }

6 }

7,输出结果: HelloWorld Christmas
=======================================================================================================

接下来,在linux下调用so试一试。
因为linux下不能用vc所以gcc,如下命令:
# gcc-I/usr/java/include-shared-olibHelloWorld.soHelloWorld.cpp
运行测试程序,发现不能导入.so文件,提示noHelloWorld in java.library.path,所以需要设置java.library.path。
java - Djava . library . path = `pwd` - cp . MyNative
注意我把.so文件拷到了当前路径,其他路径设置即可!
再执行,ok了,输出正确结果!

最后,总结一下:
jni的使用很简单,麻烦的是抽象出所调用dll或so文件的接口封装成native方法。另外就是生成so或dll文件以后的路径很不好控制。最重要的一点Java 的C调用通常不能移植到其他平台上,失去了“write once,run anywhere ”的美誉!但没违反重用性的规则。再者,需求来了,不这样实现能行吗?

java JNI 调用c或c++,windows 或 Linux系统


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论