Delphi调用Java类(支持Java 6)

 

       这两天正在做一个项目,需要使用Delphi与互联网社区网站进行对接,协议中使用了RSA加密;通过测试,Delphi的RSA算法无法与Java的RSA算法兼容,经过各种周折最终尝试了Delphi调用Java的类的方法进行RSA加密解密;这是非常令人振奋的解决方案,但是前期也遇到不少问题。

       在网上找到http://www.delphi-jedi.org/中的jni.pas及相关的例子,但是用的是jdk1.4的,问了对方说至少需要jdk1.5,差点放弃了该方案;通过各种尝试及网上搜索终于找到了一个支持jdk1.6的jni.pas接口源文件,一切豁然开朗,下面分享一下我的成果。

运行效果图

源代码:

unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, uJNI, StdCtrls;

type
  Tfmain = class(TForm)
    btnInvoking: TButton;
    mmoResult: TMemo;
    edtClassName: TEdit;
    lblClassName: TLabel;
    edtMethodName: TEdit;
    lblMethodName: TLabel;
    edtData: TEdit;
    lblData: TLabel;
    lblResult: TLabel;
    btnExit: TButton;

    procedure FormDestroy(Sender: TObject);
    procedure btnInvokingClick(Sender: TObject);
    procedure btnExitClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    FJavaVM: TJavaVM;
    FJNIEnv: TJNIEnv;
    // 加载虚拟机
    procedure LoadVM();
    // 调用Java方法
    procedure InvokingJavaMethod();
  public
    { Public declarations }
  end;

var
  fmain: Tfmain;

implementation

{$R *.dfm}

// 加载虚拟机
procedure Tfmain.LoadVM;
var
  Errcode: Integer;
  VM_args: JavaVMInitArgs;
  Options: array[0..10] of JavaVMOption;
begin
  try
    // 创建虚拟机对象,并传入jvm.DLL接口路径
    FJavaVM := TJavaVM.Create(JNI_VERSION_1_6, 'jre6\bin\client\jvm.dll');

    FillChar(Options, SizeOf(Options), #0);
    // 设置jar包或类的搜索路径,多个jar使用分号隔开
    Options[0].optionString := '-Djava.class.path=.;RSA.jar';

    // 声明使用jdk1.6版本
    VM_Args.version := JNI_VERSION_1_6;
    VM_Args.options := @Options;
    VM_Args.nOptions := 1;
    VM_Args.ignoreUnrecognized := False;

    // 加载虚拟机
    ErrCode := FJavaVM.LoadVM(VM_Args);
    if ErrCode < 0 then
    begin
      // Loading the VM more than once will cause this error
      if Errcode = JNI_EEXIST then
        MessageDlg('Java VM has already been loaded. Only one VM can be loaded.', mtError, [mbOK], 0)
      else
        ShowMessageFmt('Error creating JavaVM, code = %d', [Errcode]);
      Exit;
    end;   

    // Create the Env class
    FJNIEnv := TJNIEnv.Create(FJavaVM.Env);        
  except
    on E: Exception do
    begin
      ShowMessage('Error: ' + E.Message);
      Exit;
    end;
  end;
end;

// 调用Java方法
procedure Tfmain.InvokingJavaMethod;
var
  Cls: JClass;
  Mid: JMethodID;
  sResult: WideString;
  JStr: JString;
  sData: UTF8String;
  sMethod, sClass: PAnsiChar;
begin    
  try
    // 将传入的参数值转成UTF8字符,用于支持中文
    sData :=UTF8Encode(edtData.Text);
    // 方法名称
    sMethod := PAnsiChar(edtMethodName.Text);
    // 类名称
    sClass := PAnsiChar(edtClassName.Text);
    
    // 查找类,注意:类的路径需要做转换,如:cn.com.tcsl.RSA 应转化为 cn/com/tcsl/RSA
    Cls := FJNIEnv.FindClass(sClass);
    if Cls = nil then
    begin
      ShowMessage('Can''t find class: '+sClass);
      Exit;
    end;

    // 定位类的静态方法sMethod,并配置参数结构
    Mid := FJNIEnv.GetStaticMethodID(Cls, sMethod, '(Ljava/lang/String;)Ljava/lang/String;');
    if Mid = nil then
    begin
      ShowMessage('Can''t find method: '+sMethod);
      Exit;
    end;

    // 调用静态方法
    JStr := FJNIEnv.CallStaticObjectMethod(Cls, Mid, [sData]);

    // 将JString转化成Delphi String,注意:需要使用UTF8Decode解码UTF8字符
    sResult :=UTF8Decode(FJNIEnv.JStringToString(JStr));

    // 显示结果
    mmoResult.Lines.Add(sResult);

  except
    on E: Exception do
      ShowMessage('Error: ' + E.Message);
  end;
end;

procedure Tfmain.FormCreate(Sender: TObject);
begin
  LoadVM();
end;
procedure Tfmain.FormDestroy(Sender: TObject);
begin
  FJNIEnv.Free;
  FJavaVM.Free;
end;

procedure Tfmain.btnInvokingClick(Sender: TObject);
begin
  InvokingJavaMethod();
end;

procedure Tfmain.btnExitClick(Sender: TObject);
begin
  Close;
end;

end.

     该例子只使用了最简单的参数模式,但是一般已经够用了(即调用一个Java类的方法,传入字符,返回处理后的字符),更复杂的用法可以参考http://www.pacifier.com/~mmead/jni/delphi/JEDI/DOCS/delphi-jni-3.html

    为了方便大家调试我上传了完整的源码及jar6包,大家省事了,下载直接能够调试运行。

    源代码下载

 

 


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值