Java通过JNI调用C++动态链接库

 参考:http://www.91linux.com/html/article/program/java/20090802/17735.html

Java通过JNI调用C++动态链接库  

JAVA通过JNI调用本地方法,而本地方法是以库文件的形式存放的(在WINDOWS平台上是DLL文件形式,在UNIX机器上是SO文件形式)。通过调用本地的库文件的内部方法,使JAVA可以实现和本地机器的紧密联系,调用系统级的各接口方法。

一、 JAVA中所需要做的工作 

 程序TestDll.java  

public class TestDll {  

  //JAVA程序中,首先需要在类中声明所调用的库名称。在这里,库的扩展名字可以//不用写出来,究竟是DLL还是SO,由系统自己判断 static

  {

     System.loadLibrary("hello");

  }  

  //还需要对将要调用的方法做本地声明,关键字为native。并且只需要声明,而不需

//要具体实现。 

public native static int get();

  public native static void set(int i);

 

  public static void main(String[] args)

  {

     TestDll test = new TestDll();

     test.set(10);

     System.out.println(test.get());

  }

}

然后编译该JAVA程序文件,生成CLASS,再用JAVAH命令,JNI就会生成C/C++的头文件。 
javac TestDll.java编译它,会生成TestDll.class 
再用javah TestDll,则会在当前目录下生成TestDll.h文件,这个文件需要被C/C++程序调用来生成所需的库文件。 

注意:将TestDll.java 放在D盘下(当然可以放在其他位置)。

C:/Documents and Settings/student>javac D:/ TestDll.java

则会在D盘下生成TestDll.class.

C:/Documents and Settings/student>javah D:/ TestDll

此时会提示错误:“javadoc:错误-非法的软件包名称:D:/ TestDll”。

解决办法:转换到TestDll.class所在目录,然后使用javah命令,即

C:/Documents and Settings/student>D:

D:/>javah TestDll

此时会在D盘下生成TestDll.h。内容如下所示。

/* DO NOT EDIT THIS FILE - it is machine generated */

#include <jni.h>

/* Header for class TestDll */

 

#ifndef _Included_TestDll

#define _Included_TestDll

#ifdef __cplusplus

extern "C" {

#endif

/*

 * Class:     TestDll

 * Method:    get

 * Signature: ()I

 */

JNIEXPORT jint JNICALL Java_TestDll_get

  (JNIEnv *, jclass);

/*

 * Class:     TestDll

 * Method:    set

 * Signature: (I)V

 */

JNIEXPORT void JNICALL Java_TestDll_set

  (JNIEnv *, jclass, jint);

 

#ifdef __cplusplus

}

#endif

#endif

二、 C/C++中所需要做的工作 
对于已生成的testdll.h头文件,C/C++所需要做的,就是把它的各个方法具体的实现。然后编译连接成库文件即可。再把库文件拷贝到JAVA程序的路径下面,就可以用JAVA调用C/C++所实现的功能了。 
vs2005新建vc++ -> 类库项目,项目名称与 System.loadLibrary("hello"); 中的hello相同。将javah生成的testdll.h中内容拷贝到工程的hello.h文件,在hello.cpp文件中加入如下代码: 
int i = 0; 
JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass) 
{ 
return i; 
} 
JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint j) 
{ 
i = j; 
} 
编译时要用到一些Java里面的头文件,所以应该把位于下面目录 D:/jdk6/include 
中的所有文件都拷到 C:/Program Files/Microsoft Visual Studio 8/VC/include 目录下。 上面两个路径依自己的机子而定 若不拷到这里的话,也可以明确指定路径。或者在java程序目录下建立一个include目录,将 D:/jdk6/include 
中的所有文件都拷到该目录中。要不然会报错,说找不jni.h文件。 
vc2005中的工程项目属性中选中C/C++,在右边的附加包含目录项中加入目录:E:/ProgramLib/Java/testdll/include (这是我java程序所在的目录)。然后编译链接生成dll文件。 
将生成的DLL文件放在 C:/WINDOWS/system32 目录下,或者放在与Java程序位于相同的目录下。 

 

说明:修改TestDll.java,查看TestDll.h的变化。

修改后的TestDll.java如下。其中,test1test2 test3 test4仅仅用来查看TestDll.h的变化。

public class TestDll {

    //declare library name.

    static

    {

       System.loadLibrary("hello");

    }

    //declare names of methods to be called.

    public native static int get();

    public native static void set(int i);    

    //just for test.

    public void test1(){}

    public void test2(){}

    public String test3(){return null;}

    public int test4(){return 0;}   

    public static void main(String[] args)

    {

       TestDll test = new TestDll();

       test.set(10);

       System.out.println(test.get());

    }

}

对应修改后的TestDll.javaTestDll.h如下。

#define _Included_TestDll

#ifdef __cplusplus

extern "C" {

#endif

/*

 * Class:     TestDll

 * Method:    get

 * Signature: ()I

 */

JNIEXPORT jint JNICALL Java_TestDll_get

  (JNIEnv *, jclass);

 

/*

 * Class:     TestDll

 * Method:    set

 * Signature: (I)V

 */

JNIEXPORT void JNICALL Java_TestDll_set

  (JNIEnv *, jclass, jint);

 

#ifdef __cplusplus

}

#endif

#endif

可见,TestDll.h并无变化。因此,TestDll.h只是针对Java 要访问的库中的方法进行声明。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值