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

本文详细介绍了如何使用Java的JNI技术在Windows和Linux环境下调用C/C++代码。通过创建Java类,生成JNI头文件,编写C/C++实现,编译成DLL或SO文件,并进行测试,展示了具体步骤。虽然JNI调用可能影响Java的跨平台特性,但在特定需求下仍然是必要的解决方案。
   由于java程序需要调用C或C++的代码,不得不使用JNI。C的代码在Win32和Linux下都有相同功能的不同实现,就像JDK分几种平台版本(win32,linux,solaris等)。
   
首先,看一看首先,看一看win32下调用dll文件。
    1, 新建HelloWorld.java
 1public class HelloWorld
 2
{
 3  static

 4  {
 5    try

 6    {
 7      //此处即为本地方法所在链接库名

 8      System.loadLibrary("HelloWorld");
 9    }
catch(UnsatisfiedLinkError e){
10      System.err.println( "不能加载dll文件:/n " +
e.toString() );
11    }

12  }
//end static
13 public native void SayHello(String strName);
14

15}

16
  2,  编译java文件生成HelloWorld.class文件
  3,在命令行下,javah -jni HelloWorld 生成 HelloWorld.h 文件
  
 1/* DO NOT EDIT THIS FILE - it is machine generated */
 2#include <jni.h>
 3/* Header for class HelloWorld */
 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 */

15JNIEXPORT void JNICALL Java_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中函数声明相同
 5JNIEXPORT void JNICALL Java_HelloWorld_SayHello (JNIEnv * env, jobject arg, jstring instring)
 6
{
 7//从instring字符串取得指向字符串UTF编码的指针

 8  const jbyte *str = 
 9   (const jbyte *)env->
GetStringUTFChars( instring, JNI_FALSE );
10printf("HelloWorld,%s/n"
,str);
11  //通知虚拟机本地代码不再需要通过str访问Java字符串。

12env->ReleaseStringUTFChars( instring, (const char *)str );
13return
;
14}
 
15int
 WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
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
1public class HelloWorld {
2public static void main(String args[]){
3        HelloWorld hw = new HelloWorld();
4        hw.SayHello("Christmas");    
5    }

6}

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

 接下来,在linux下调用so试一试。
 因为linux下不能用vc所以gcc,如下命令:
#gcc -I/usr/java/include -shared -o libHelloWorld.so HelloWorld.cpp 
    运行测试程序,发现不能导入.so文件,提示no HelloWorld  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 ”的美誉!但没违反重用性的规则。再者,需求来了,不这样实现能行吗?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值