千里冰封
JAVA 浓香四溢
posts - 151,comments - 2801,trackbacks - 0
昨天我们讲了要开发JNI的几个工具的安装和下载,今天我们讲它们的基本使用.为了验证我们昨天的PATH确实设好了.我们可以进入CMD下面,输入如下语句:gcc --version
如果输出类似如下的话,就说明安装正确了:

gcc (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


既然我们这个已经装好了,现在就打开Netbeans6.0吧.Netbeans6.0现在提供的下载分几个版本,我们下载的是完全版,就是什么功能都有的,完全版最大,如果下载别的版本的话,就不能用它来做C/C++的程序了.启动速度当然就最慢了.启动的时候,耐心的等待一下,反正启动界面挺好看的.

好了,Netbeans启动了,我们先建一个JAVA工程,名字就叫TestNative吧.如何使用Netbeans就不是本文的目的了:).大家可以去参考别的资料。然后在TestNative里面建一个类,就叫testnative1.Main吧。然后在里面写上如下的内容:.

/*
 * Main.java
 *
 * Created on 2007-10-19, 17:23:02
 *
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 
*/

package testnative1;

/**
 *
 * 
@author hadeslee
 
*/
public class Main {

    
/**
     * 
@param args the command line arguments
     
*/

    
public static void main(String[] args) {
        
// TODO code application logic here
        Main m=new Main();
        System.loadLibrary(
"cygHello");
        m.sayHello(
"hadeslee");
       
    }
    
public native void sayHello(String who);
   

}


在这里我们可以看到,我们定义了一个native的方法,叫sayHello,它接受一个String做为参数,我们编译一下这个文件,然后转到此工程的build/classes文件夹下面,执行如下命令:
javah testnative1.Main
如果正常的话,就会在你运行命令的目录下产生一个testnative1_Main.h的文件。至此,我们JAVA部份的工作就告一段落了。

然后我们新建一个C/C++的工程,选择C/C++ Dynamic Library。意思是动态链接库。工程名就叫Hello吧。

打开这个工程,在Header Files节点下,建一个C++的头文件,就叫HelloH.h吧。进入这个文件以后,我们把刚刚生成的testnative1_Main.h内容复制到它里面去。 这样头文件就建好了。然后再在Source Files节点下,建一个Empty C++ File。把如下的内容复制过去:

#include <jni.h>
#include 
<stdio.h>
#include 
"HelloH.h"
JNIEXPORT 
void JNICALL Java_testnative1_Main_sayHello
        (JNIEnv 
* env, jobject obj, jstring s){
    
const char* who;
    who
=env->GetStringUTFChars(s, 0);
    printf(
"你好:%s", who);
    env
->ReleaseStringUTFChars(s,who);
}



这个时候,你会发现很多错误提示,别急,我们一个一个来解决,首先对着你的Hello工程点右键,然后再点Properties。找到如图所示的地方,添加我们的引用的头文件,这个引用是SUN公司给我们定义好的头文件,就是供我们开发JNI的时候用的。



这里有一点要注意的就是,不要直接引用到JDK里面的头文件,最好是把它里面的include文件夹拷出来,因为我们默认安装的java是装在C:\program files下面的,因为有空格,所以cygwin将不能识别,在我这里我是把它拷出来放在D盘的根目录下。然后再找到Command Line这个地方,加上如下的几个命令:
-mno-cygwin -Wl,--add-stdcall-alias -shared -m32

至此,我们的事情就完成了大部份了,然后我们编译生成整个Hello工程就可以了,如果不出意外的话,就可以在dist目录下面找到一个叫cygHello.dll的文件,我们把这个文件拷到我们的TestNative工程的根目录下,执行一下我们的Main类,发现了没有,我们的native方法 有输出了。我们现在只是生成了一个在windows下面使用的动态链接库,如果我们要生成能在linux,Mac ,Solaries平台下的呢。别急,有cygwin,一切都可以搞定了。我们要生成别的平台的库文件,只要在General里面选中相应的平台就可以了。不过最好的办法还是去相应的平台下载cygwin,然后再重新用我们这个工程,经过少量的改动,重新生成一下,只需要改动的地方有,include要改一下,因为在windows下面我们include的目录和linux当然不一样。还有就是在linux下面编译的时候,不再需要-mno-cygwin -Wl,--add-stdcall-alias -shared -m32这个命令了。直接生成就可以了,在linux下面会生成一个叫libHello.so的文件,我们JAVA代码只要导入Hello就可以了,lib的前缀不需要再导入了,因为linux下面库文件都是带lib前缀的。

我这里用的linux环境是ubuntu,一切都正常,在ubuntu下可以看到正常的输出。只是你一样要把它放到java.library.path里面去,这样JVM才能找得到它。构建跨平台的jni并不是一件非常容易的事情,但是从一个小小的例子可以看出JNI方面的一些东西。祝大家玩得愉快。





尽管千里冰封
依然拥有晴空

你我共同品味JAVA的浓香.
posted on 2007-10-20 10:09 千里冰封 阅读(2130) 评论(1)  编辑  收藏 所属分类: JAVASE

FeedBack:
# re: 构建跨平台的JNI实现(下)
2007-10-20 18:26 | 海边沫沫
沙发  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: