• 转: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_15jre

    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


    ————————————————
    版权声明:本文为CSDN博主「cangwu_lee」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/cangwu_lee/java/article/details/2211517

  • 相关阅读:
    ShopEx customSchema 定制能够依据客户的需求对站点进行对应功能的加入改动或者删除
    Android 屏幕旋转 处理 AsyncTask 和 ProgressDialog 的最佳方案
    NYOJ 46 最少乘法次数
    彻底理解position与anchorPoint
    链路层
    留不住的2015
    javascript笔记
    <html>
    高性能站点建设指南-前端性能优化(一)
    监听器设计模式
  • 原文地址:https://www.cnblogs.com/timba1322/p/12678515.html
Copyright © 2020-2023  润新知