JNI简单实现Java调用C++/C的HelloWorld

来源:互联网 发布:程序员人才需求 编辑:程序博客网 时间:2024/05/22 12:24

http://blog.csdn.net/ididcan/article/details/6828982

简介

JVM封装了各种操作系统实际的差异性的同时,提供了JNI技术,它是一种双向的接口,使得开发者可以通过Java代码调用到各种native的 库,反之亦然。所以JNI(JavaNative Interface)能作为Java语言的一部分,她能够作为粘合剂将Java应用和其他本地应用(C/C++,Delphi)集合在一起.

下图就很好的描述了JNI在Java应用中的地位和角色:

                             

作为一个双向的接口,JNI能支持两种native代码:native libraries 和native applications.

(1)你能使用JNI去写一些native methods去允许javaApplications能呼叫native libraries中的函数,native methods的具体实现是可能C,C++或者Delphi

(2)JNI也支持嵌入一个JVM实现到一个本地应用程序中去,去执行那些用Java语言编写的的模块.比如,一个C++编写的浏览器利用内嵌的JVM去执行下载到本地的applet.

实现”JNI-Java invoke Native Library”的一般步骤如下:

1) 完成Java代码,编写好Java调用类

2)编译你的Java类

3)用javah生成编译好的class文件对应的C/C++  函数的头文件

4) 实现头文件中的函数原型,编写native代码

5) 将native代码编译打包成DLL库(win32)或共享库(Linux)

6)将你的Java代码跑起来

 

 

实践

功能:利用JNI接口调用C++中实现的HelloWorld!

环境:VS2008,Eclipse 3.7

1)首先在Eclipse中建立一个工程。具体如下:

            a)新建一个HelloWorld工程。

            b)在工程中建立一个类,这里简单的建立一个HelloWorld类,如下所示:

[java] view plain copy
print?
  1. public class HelloWorld {  
  2.     static {  
  3.         System.load("D:\\UDMS\\Project\\HelloWorld\\HelloWorld.dll");  
  4.         //System.loadLibrary("HelloWorld");  
  5.     }  
  6.       
  7.     public native static void hello();  
  8. }  


            PS:有关load和loadLibrary的区别可以google之。这里我想说明一点就是他们之间最大的区别就是使用的路径不同,一个使用的是绝对路径,一个使用的是相对路径。注意这里的相对路径是与SRC目录平行的。否则可能出现找不到该dll文件的错误。还有一个很大区别就是后缀名了。     

            c)在上述代码中一定要讲hello方法设置为native方式。

            d)可以建立一个测试文件。如下所示

[java] view plain copy
print?
  1. public class Test {  
  2.     public static void main(String[] args){  
  3.         HelloWorld.hello();  
  4.     }  
  5. }  


 

2)得到C头文件HelloWorld.h

             a)编译生成的class文件:HelloWorld.class

             b)在工程的bin目录下建立run.bat,内容如下:

[plain] view plain copy
print?
  1. set java_home=D:\Program Files\Java\jdk1.6.0_26  
  2. set path=%java_home%\bin  
  3. set class_path=%java_home%\lib;%java_home%\lib\dt.jar;;%java_home%\lib\tools.jar  
  4. javah -jni HelloWorld  
  5. @pause  

             当然其中的路径根据实际情况的不同而不同。运行run.bat,得到对应的C头文件HelloWorld.h

 

3)建立C++工程HelloWorld。建立过程如下所示:

            a)新建一个项目HelloWorld,选择Win32项目,点击下一步,如下图所示

 

            b)点击下一步(不要点完成)

 

           

             c)注意这里应该选择DLL

 


 

4)建立完工程之后需要做以下操作

            a)将刚才生成的头文件HelloWorld.h加入到该项目的头文件夹中,并且将头文件中的声明拷到HelloWorld.cpp中。并且实现。

            b)此后还要将dllmain.cpp文件中的内容拷到HelloWorld.cpp中,因为现在函数的入口在HelloWorld.cpp中。删除该dllmain,代码如下:

[cpp] view plain copy
print?
  1. #include "stdafx.h"  
  2. #include "HelloWorld.h"  
  3. //<span style="color:#ff6666;">加入头文件</span>  
  4. BOOL APIENTRY DllMain( HMODULE hModule,  
  5.                        DWORD  ul_reason_for_call,  
  6.                        LPVOID lpReserved  
  7.                      )  
  8. {  
  9.     switch (ul_reason_for_call)  
  10.     {  
  11.     case DLL_PROCESS_ATTACH:  
  12.     case DLL_THREAD_ATTACH:  
  13.     case DLL_THREAD_DETACH:  
  14.     case DLL_PROCESS_DETACH:  
  15.         break;  
  16.     }  
  17.     return TRUE;  
  18. }  
  19.   
  20. JNIEXPORT void JNICALL Java_HelloWorld_hello  
  21. (JNIEnv *env, jclass hello){  
  22.     printf("Hello World\n");  
  23.   
  24. }  

            c)将jni.h,jni_md.h,jawt_md.h拷入工程目录下,这些文件都在你的JAVA本地路径下的bin文件夹中。在HelloWorld.h文件中将#include <jni.h>改为#include "jni.h"(包含本地路径搜索)

            d)最后工程如下图所示:

5)生成DLL文件(以下我是参照网上的材料,不知道其中的一些步骤是否需要,大家可以试试)

            a)在项目的属性中如下设置:


            b)选择配置的类型,如下图所示:

 

            c)接下来要注意了,如果你的DLL要用在外部那么就要选择Release进行编译。同样的由于平台的不同,需要选择X86和X64。

                 具体选择方法可以参照下面一个文章:http://blog.csdn.net/n_ithero/article/details/5403978

            d)生成-》生成解决方案,在本地目录中的Release文件夹中就可以找到一个dll文件,将该dll文件加到eclipse项目HelloWorld中与src平行。

至此完成了整个过程。

如有不解,欢迎回复

原创粉丝点击