Java JNI 和 Delphi 相互調用(1)-JAVA調用DELPHI

JNI 不是什麼新技術,英文全稱是:Java Native Interface,JAVA本地化代碼接口。本地化代碼是指直接編譯成的與機器相關的二進制代碼,而不是Java字節碼之類的中間代碼。對於 JNI 的來龍去脈,不作介紹了,在 java.sun.com 有介紹,另外 BAIDU/GOOGLE 搜索,也有大把的。這裏僅僅做一個入門級的介紹和實現。

JAVA發佈的是C/C++的接口文檔,DELPHI想調用,首先要轉換成DELPHI的接口文檔。很幸運,已經有人完成此項工作了,請看網站:http://delphi-jedi.org/ ,在網站中下載 JNI-JEDI.zip ,解出來後,將pas文件放在我們要創建的工程的源文件一塊就可以了。

好,下面準備進入主題。

一、先介紹 JAVA 調用 DELPHI 的過程
1、創建一個 JavaCallDelphi .java,文件的內容:

public   class  JavaCallDelphi  {
    
static {
        System.loadLibrary(
"JavaCallDelphi");
    }

    
public native void sayHello(String s);
    
public native String echo(String s);
    
public native void showForm(String s);
    
    
public static void main(String[] args) {
         JavaCallDelphi jc 
= new JavaCallDelphi();
         System.out.println(
"java say: echo() returned:"+jc.echo("華夏上下午千年") );
         jc.sayHello(
"橙子");
         jc.showForm(
"華夏上下午千年");
    }

}

 
為了簡單,這裏就不創建“包”了。我們將這個 class 保存成無 BOM 的 UTF-8 格式文件。再用下面這個命令行進行編譯:
javac -encoding utf-8 JavaCallDelphi.java
這個 class 現在是不能執行的,因為還沒有 JavaCallDelphi.dll 。

2、創建 Delphi 的庫工程
先提一下JAVA的類和方法的命名和DELPHI中的函數的命名的規律。
在DELPHI中的函數,以Java開頭,用下劃線將Java類的包名、類名和方法名連起來。本例中沒有包名,忽略了。同時,在Win32平台上,此過程的調用方式只能聲明為 stdcall。
例如,Delphi中的方法:
procedure Java_JavaCallDelphi_sayHello(PEnv: PJNIEnv; Obj: JObject; S: jstring); stdcall;
方法中的參數,前兩個是固定的,有什麼用請看後面的 DELPHI 的代碼,不深入講解;後面的參數就是 JAVA 和 DELPHI 之間傳送的參數。JAVA 的數據類型轉換到 DELPHI 的數據類型,在 jni.pas 中有定義。

JavaCallDelphi.dpr 的代碼:


library JavaCallDelphi;

uses windows, SysUtils, Classes, jni, Forms, StdCtrls;

procedure Java_JavaCallDelphi_sayHello(PEnv: PJNIEnv; Obj: JObject; S: jstring); stdcall;
var JVM: TJNIEnv;
begin
   JVM:
=  TJNIEnv.Create(PEnv);
   Writeln(
' Delphi say: ' + JVM.UnicodeJStringToString(s) + ' ,您好!看到效果了吧。 ' );
   JVM.Free;
end;

function Java_JavaCallDelphi_echo(PEnv: PJNIEnv; Obj: JObject; arg: JString): JString; stdcall;
var tmpStr, s1: String;      JVM: TJNIEnv;
begin
   JVM:
=  TJNIEnv.Create(PEnv);

   Write(
' Delphi say:jvm Version : ' );
   Write(jvm.MajorVersion);  Write(
' . ' );
   Write(jvm.MinorVersion);
   Writeln(
'' );

   s1:
= JVM.UnicodeJStringToString(arg);
   tmpStr :
=   ' 傳入的參數是: " '   +  s1  +   ' "。 ' ;

   Writeln(
' Delphi say: parameter is: ' + s1);
   Writeln(
' Delphi say: return string: ' + tmpStr);
   result :
=  JVM.StringToJString( PChar(UTF8Encode(tmpstr)) );
   JVM.Free;
end;

procedure Java_JavaCallDelphi_showForm(PEnv: PJNIEnv; Obj: JObject; arg: JString);stdcall;
var f:TForm; edit: TEdit;   tmpStr: String;  jvm:TJniEnv;
begin
    jvm:
= TJniEnv.Create(PEnv);
    tmpStr :
=  JVM.UnicodeJStringToString(arg);
    f:
= TForm.Create(nil);
    f.SetBounds(
100 100 400 200  );
    
    Edit :
=  TEdit.Create(f);
    Edit.Parent :
=  f;
    Edit.Show();
    Edit.Left  :
=   0 ;
    Edit.Top   :
=   0 ;
    Edit.Width :
=   390 ;

    edit.Text :
=   ' Java傳過來的參數是: ' + tmpstr;
    f.ShowModal();
    freeAndNil(f);
    freeAndNil(jvm);
end;

exports
   Java_JavaCallDelphi_sayHello, 
// 為函數做引出聲明,這樣才能被調用
   Java_JavaCallDelphi_echo,
   Java_JavaCallDelphi_showForm
   ;
begin

end.


準備做命令行編譯,別忘記jni.pas和jni_md.inc放在一塊,編譯命令:
dcc32 /B JavaCallDelphi.dpr


3、執行、測試
將這幾個命令行的編譯做成一個批處理文件:

@ECHO   OFF
rem  java的執行的參數. 根據實際的環境,修改參數中的編碼名稱/語言名稱/地區名稱
rem
 編碼名稱/語言名稱/地區名稱, 要和操作系統相對應,否則會出現亂碼.
SET  PA = -Dclient . encoding . override = big5 -Dfile . encoding = big5 -Duser . language = zh -Duser . region = TW

rem  jre所在的路徑,像 JAVA_HOME 一樣指向安裝的目錄
SET  JRE_HOME = C: sdk/ jdk1 . 5 . 0_15 jre

SET   PATH = % PATH % ; C: /Program  Files /borland/ Delphi7/ Bin
SET   PATH = % PATH % ; %JRE_HOME% /bin/ client


REM  編譯delphi的工程
dcc32  / B JavaCallDelphi . dpr

rem  java 的編譯命令行
javac -encoding big5 JavaCallDelphi . java

echo .

rem  執行demo
java %PA% JavaCallDelphi


保存成 JavaCallDelphi.cmd ,雙擊執行,即看到結果,如圖:

JavaCallDelphi.jpg






























程序比較簡單,就不做注釋,在關鍵的地方作了說明。
調試運行的環境:
Windows XP SP2(繁體中文)
JDK1.5、JRE1.5
Delphi 7
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值