JNI的研究
以下是我个人的经验
虽然JAVA的程序都必须在JAVA的虚拟机器上执行,但是我们可以在这部机器中打一个洞,让JAVA程序可以直接沟通实际的机器
JNI是一种让JAVA程序可以外接外部程序的一种机制,让JAVA程序更具有扩充性,下面将示范一个简单的范例,这个范例中说明JAVA程序如何与C语言接轨,事实上昨天所谈的Prolog就是利用这种方式使Java程序可以使用prolog,透过dll和native的方式来达成这项任务,经过这样的测试与实验之后让我不得不佩服java这个程序语言
你不需要担心程序方面的问题,因为底下的程序架构都相当简单,主要只是让我们体验一下

工具介绍:我将使用visual c++ 6.0来制作dll,使用java sdk 1.4来编译我的java

java部分的实作


class HelloWorld {


public native void displayHelloWorld();← 左方的native型态是通知Java这个函数会使用到外部函数


 


static {


System.loadLibrary("hello"); ← 左方的程序代码代表我要加载hello.dll的动态连结,hello.dll的制作我在稍后会做介绍


}


 


public static void main(String[] args) {


new HelloWorld().displayHelloWorld();


}


}

当你完成上述的程序之后,将这个程序存盘为'HelloWorld.java'先用'javac HelloWorld.java'这个指令将它组译成HelloWorld.class,然后使用'javah HelloWorld'产生HelloWorld.h,在HelloWorld.h中我们知道我们要实作一个函数Java_HelloWorld_displayHelloWorld(JNIEnv *, jobject); 接下来我将介绍如何完成这个函数
实作生平的第一个dll,在之前知道在windows和linux下有一种叫dll,动态连结的机制,但是一直不晓得到底它是怎么做的,今天将要实作第一个这样的东西
我会尽量将东西描述清楚,因为这是我第一次的经验
首先启动visual c++ 6.0,在档案中选择新增,然后在project中选择Win32 Dynamic-Link Library这个选项,然后填写你项目的名称'hello',按下'Ok',请选择An empty Dll project这一选项,然后按'Finish'再按下'Ok',我们要从头开始。
经过上述动作之后我们就会得到一个空的项目数据,然后我们需要增加一些程序到我们的项目中,在这之前我们先处理好我们的.h文件,首先先到你安装java JDK的目录下找到include的数据夹,为了以后撰写程序方便,将这个目录下的所有档案复制一份到你安装visual c++ 6.0目录下VC98/Include里面,预设路径为C:/Program Files/Microsoft Visual Studio/VC98/Include,将数据复制到此数据夹中,并将原本放在win32中的jawt_md.h和jni_md.h复制一份至C:/Program Files/Microsoft Visual Studio/VC98/Include
完成这些前置动作之后,再来将我们刚刚产生的HelloWorld.h加入我们的Header Files中,并新增一个.c的档案HelloWorldImp.c,然后到上方的菜单中Build选则'Build hello.dll',然后你将会得到一个hello.dll在项目目录下的Debug/hello.dll,到此为止,如果顺利你应该的到dll檔

程序代码如下(HelloWorldImp.c):

#include 
 
  
#include "HelloWorld.h" 
 
  
#include 
 
  

      
  
 
  
JNIEXPORT void JNICALL 
 
  
Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj) 
 
  
{ 
 
  
printf("HelloWorld"); 
 
  
 
   return 
   ; 
 
}
 
程序代码如下 
    (HelloWorld.h) 
 
/* DO NOT EDIT THIS FILE - it is machine generated */ #include 
 
    
/* Header for class HelloWorld */ #ifndef _Included_HelloWorld #define _Included_HelloWorld 
 
    
#ifdef __cplusplus extern "C" { #endif 
 
    
/* 
 
    
* Class: HelloWorld 
 
    
* Method: displayHelloWorld 
 
    
* Signature: ()V 
 
    
*/ 
 
    
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld 
 
    
(JNIEnv *, jobject); 
 
    
#ifdef __cplusplus } #endif 
 
    
#endif

然后将 hello.dll 和 HelloWorld.class 放在同一个目录下,执行 java HelloWorld ,出现打印 HelloWorld 在画面上的结果
以上这是一个小小的范例,目的只是在做一个小小的实验,因为没有一个人会因为要打印一串自救去呼叫 C 语言来帮你做事,而会直接使用 System.out.print("HelloWorld") ,比较快一点
透过以上这个小实验让我们知道 java 和 c 之间是有办法互通的,因此或许 java 可以透过这个方式与操作系统之间有更密切的互动