JNI的简单使用

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

使用的简单流程:

一、Java中所需要做的工作

1、在Java程序中,首先需要在类中声明所调用的库名称,如

[java]  view plain copy
  1. static {  
  2. System.loadLibrary(“testdll”);  
  3. }  

这里库的扩展名可以不用写出来,究竟是DLL还是SO,由系统自己判断

2、还需要对将要调用的方法做本地声明,关键字为native。且只需要声明,而不需要具体实现

[java]  view plain copy
  1. public native static void set(int i);  
  2. public native static int get();  

得到的Java程序如下:TestJNI.java

[java]  view plain copy
  1. public class TestJNI {  
  2.     static {  
  3.         System.loadLibrary("testdll");  
  4.     }  
  5.     public native static int get();  
  6.     public native static void set(int i);  
  7.     public static void main(String[] args) {  
  8.         testdll test = new testdll();  
  9.         test.set(10);  
  10.         System.out.println(test.get());  
  11.     }  
  12. }  
3、 使用javac TestJNI.java编译它,得到TestJNI.class

再用javah TestJNI,则会在当前目录下生成TestJNI.h文件

 注意:用javah命令生成相应h头文件的时候有可能会出现无法找到相应class文件的错误,建议使用如下格式在控制台生成.h头文件
D:\>javah -classpath . testdll

二、C/C++中所需要做的工作

1、打开VC++,新建工程->win32 DLL,在向导中选择空工程。然后编写testdll.cpp文件

[cpp]  view plain copy
  1. #include <windows.h>  
  2. #include "TestJNI.h"  
  3. int i = 0;  
  4. JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass)  
  5. {  
  6. return i;  
  7. }  
  8. JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint j)  
  9. {  
  10. i = j;  
  11. }  
  12. int WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)   
  13. {   
  14. return TRUE ;   
  15. }  

说明:

(1)必须有DllMain函数,并且DllMain必须返回TRUE,否则系统将终止程序并弹出一个“启动程序时出错”对话框,其他两个为Java中调用的两个函数的实现,解释见最后的补充

(2)把Java编译生成的TestJNI.h加入到C/C++的工程中,否则上面代码的include "TestJNI.h"无法引用到

2、编译上面的testdll.cpp文件,可以生成testdll.dll文件,但是这过程通常会出现:在TestJNI.h中找不到jni.h

解决方法:把Javajdk中的下面这些.h文件复制一份到Microsoft Visual Studio的安装目录下的\VC\include文件夹下,例如笔者的是D:\Program Files\Microsoft Visual Studio 10.0\VC\include

[plain]  view plain copy
  1. \jdk\include\jni.h  
  2. \jdk\include\win32\jawt_md.h  
  3. \jdk\include\win32\jni_md.h  

三、结合起来

1、生成的DLL文件的名称要跟Java代码中需要调用的testdll一样,如果不同可以修改文件名,这里是testdll.dll

2、然后把该dll文件拷贝到TestJNI.class文件的目录下。

3、使用java testdll 运行它,就可以观察到结果

说明:如果运行java testdll 出现错误:“ 找不到或无法加载主类”,可能是环境变量的classpath键值的分号;掉了,一般掉了这个就会出现这种问题

四、最后对TestJNI.h的内容理解补充

[plain]  view plain copy
  1. /* DO NOT EDIT THIS FILE - it is machine generated */  
  2. #include <jni.h>  
  3. /* Header for class TestJNI*/  
  4. #ifndef _Included_TestJNI  
  5. #define _Included_TestJNI  
  6. #ifdef __cplusplus  
  7. extern "C" {  
  8. #endif  
  9. /*  
  10. * Class: TestJNI  
  11. * Method: get  
  12. * Signature: ()I  
  13. */  
  14. JNIEXPORT jint JNICALL Java_TestJNI_get (JNIEnv *, jclass);  
  15. /*  
  16. * Class: TestJNI  
  17. * Method: set  
  18. * Signature: (I)V  
  19. */  
  20. JNIEXPORT void JNICALL Java_TestJNI_set (JNIEnv *, jclass, jint);  
  21. #ifdef __cplusplus  
  22. }  
  23. #endif  
  24. #endif  
在具体实现的时候,我们只关心两个函数原型
JNIEXPORT jint JNICALL Java_TestJNI_get (JNIEnv *, jclass); 和
JNIEXPORT void JNICALL Java_TestJNI_set (JNIEnv *, jclass, jint);
这里JNIEXPORT和JNICALL都是JNI的关键字,表示此函数是要被JNI调用的。而jint是以JNI为中介使JAVA的int类型与本地的int沟通的一种类型,我们可以视而不见,就当做int使用。函数的名称是JAVA_再加上java程序的package路径再加函数名组成的。参数中,我们也只需要关心在JAVA程序中存在的参数,至于JNIEnv*和jclass我们一般没有必要去碰它。 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值