研究報告
 
 
[閱讀心得]
 
Definition: The Semantic Web is the representation of data on the World Wide Web.
 
It is a collaborative effort led by W3C with participation from a large number of researchers and industrial partners. It is based on the Resource Description Framework (RDF), which integrates a variety of applications using XML for syntax and URIs for naming. The Semantic Web is an extension of the current web in which information is given well-defined meaning, better enabling computers and people to work in cooperation.

-- Tim Berners-Lee, James Hendler, Ora Lassila, The Semantic Web, Scientific American, May 2001
From: http://www.w3.org/2001/sw/
 
 
[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部分的實作
程式碼如下(HelloWorld.java):
class HelloWorld { 
        //native型態是通知Java這個函數會使用到外部函數 
        public native void displayHelloWorld();
        static { 
                //我要載入hello.dll的動態連結,hello.dll的製作我在稍後會做介紹
                System.loadLibrary("hello"); 
        }

        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可以透過這個方式與作業系統之間有更密切的互動
[prolog與Java連接的簡單範例]

採用LPA prology 4320內的Intelligence Agent,目的在練習JNI的使用方式
主程式檔:(Jprology.java)
class Jprolog
{
public static void main(String argv[]){
Int386w flex = new Int386w(); ←使用Int386w類別的資料定義在下方
String ResultString;
int i=flex.loadProlog("");
System.out.println("test"+i);
ResultString=flex.initGoal("ensure_loaded('hello.pl'). ");
System.out.println(ResultString);
ResultString=flex.callGoal();
System.out.println(ResultString);
flex.exitGoal();
System.out.println(ResultString);
ResultString=flex.initGoal("run. ");
System.out.println(ResultString);
ResultString=flex.callGoal();
System.out.println(ResultString);
/*tellGoal應該是找出所有結果(不確定)*/
//ResultString = flex.tellGoal( ResultString );
//System.out.println("2 "+ResultString);
flex.exitGoal();
/*想辦法了解JAVA字串的處理,因為ResultString的前6個字是訊息旗標*/
}

};

prolog程式(hello.pl)
/*
test file
*/
run:-
write('hello').

類別檔(Int386w.java)
public class Int386w
{
private int Id;

public static int isERR_ENCODE = -1;
public static int isERR_TICKLE = -2;
public static int isERR_CMUTEX = -3;
public static int isERR_WMUTEX = -4;
public static int isERR_LOCATE = -5;
public static int isERR_CREATE = -6;
public static int isERR_MAPFIL = -7;
public static int isERR_MODULE = -8;
public static int isERR_PROLOG = -9;
public static int isERR_ACTIVE = -10;
public static int isERR_WINDOW = -11;

public int loadProlog( String s )
{
return( loadProlog( s, 0, 0 ) );
}

public int loadProlog( String s, int desire, int tickle )
{
Id = nativeLoadProlog( s, desire, tickle );
return Id;
}

public int haltProlog()
{
if( nativeHaltProlog(Id) != 0 ) {
Id = 0;
return 1;
} else
return 0;

}

public String initGoal( String Goal )
{
return nativeInitGoal( Id, Goal );
}

public String callGoal( )
{
return nativeCallGoal( Id );
}

public String tellGoal( String Goal )
{
return nativeTellGoal( Id, Goal );
}

public int exitGoal( )
{
return nativeExitGoal(Id);
}


native int nativeLoadProlog( String s, int desire, int tickle );
native int nativeHaltProlog( int prolog );
native String nativeInitGoal( int prolog, String goal );
native String nativeCallGoal( int prolog );
native String nativeTellGoal( int prolog, String goal );
native int nativeExitGoal( int prolog );

static {
System.loadLibrary( "jint386w" );
}

public void finalize() {
if( 0 != Id ) {
haltProlog();
Id = 0;
}
}
}

所使用的jint386w.dll請至prology安裝路徑\SERVER\INCLUDES下取得

在java中呼叫使用prology的方法說明:
請至prology安裝路徑\SERVER\INCLUDES下取得下列檔案並包入JAVA專案的資料夾中jint386w.dll,int386w.DLL,Int386w.java(上面所提到的類別檔),然後到prology安裝路徑下取得INT386W.OVL,PRO386W.EXE,有了這些檔案就可以透過java去執行prolog程式
如果你想要執行flex程式那麼你需要額外取得FLEX.PC,在prology安裝路徑\SYSTEM下可找到,另外使用FlexIS類別來協助處理,請至prology安裝路徑\SERVER\INCLUDES下取得
如果不想透過FlexIS類別來協助處理,可以先自行載入initialization( load_files(flex) ) .,這個是flex的執行環境,當然你必須取得FLEX.PC,利用initGoal("initialization( load_files(flex) ). ")語法載入環境,再載入flex

使用心得:因為只是稍微試試看,所以並沒有很多經驗
1. initGoal("x."),給我的感覺好像是在prolog之中直接下達x.的命令,或是在程式中的:-x.這樣的句法
2. callGoal()這個東西我覺得相當於你在prolog中按下enter執行命令,它會回傳字串給java,這字串中包含一些訊息碼與答案
3. exitGoal()程式執行完畢將prolog關閉

我的範例在C:\jtest\m5

執行結果
test1
G 0000

T 0000

T 0000

G 0000

T 0000
hello
 
[prolog中文亂碼的解決]

解決prolog中文亂碼的問題


原因:因為prolog內部程式的編碼是採用unicode的方式做編碼處理,所以遇到中文的big5碼時會發生錯誤。
 
解決的方法:我們利用建立對照表的方式將unicode轉換成big5碼,因為資料量很龐大,大約有六萬多筆資料,所以我們透過資料庫來儲存大量資料。
 
透過此中文轉碼處理之後我們可以正確的顯示中文碼。程式檔存放在mycalendar[檔案總管]中的'prolog中文問題處理'資料夾內,其中'B2U'資料夾中所存放的是利用prolog的fact當作資料庫來做資料的比對,'B2U_Database'資料夾中所存放的是透過資料庫存放轉碼資料。

 

使用說明


程式語言:LPA prolog
程式的入口為big5(Unicode,Big5)
Unicode為顯示時出現中文亂碼的部分,系統此亂碼用unicosde編碼,Big5是正確的中文字

範例:


當我們使用prodata去抓取資料時如果欄位中的資料是中文碼,則抓出了資料會出現亂碼
下面為連接資料庫並轉為中文碼的範例(有關資料庫的連結請參閱使用說明)

ensure_loaded( system(dblink) ).
ensure_loaded('prologBig5.pl').
db_connect( 'rdfword' ).
db_attach( words, 'words' ).
words(A,B,C,D,E,F,G,H,I,J,K,L),big5(A,X1),big5(B,X2),big5(C,X3).


解說:前三行程式是做資料庫的連結,我們是透過ODBC去連結資料庫,其中資料庫的名字叫'rdfword',資料表的名字叫'words',這個資料表有十二個欄位,取出時二個欄位分別為A,B,C,D....,分別將前三個欄位的中文碼正確顯示
 

    全站熱搜

    CJY0503 發表在 痞客邦 留言(0) 人氣()