起步软件技术论坛-X3

 找回密码
 立即注册
搜索
查看: 468|回复: 13

[分享]调用服务端的dll函数库**

[复制链接]
发表于 2008-1-2 10:21:33 | 显示全部楼层 |阅读模式
服务器一个dll函数库,需要在客户端上调用这个函数,通常的做法是利用windows的RPC机制,比如把dll函数库做成一个服务端的对象,在客户端利用CreateRemoteObject的方式创建这个对象,然后调用其中的方法。这样的方式需要服务端开放RPC端口才可以,对于互联网应用不是很安全。

平台中,客户端和服务端通过http协议进行通讯,缺省使用8081端口,也可以配置使用标准的80端口,我们可以利用这个端口去调用服务器端的函数,这个函数其实是在服务端执行的,可以在客户端触发服务端的执行,并且可以传递参数。

基本实现原理是:
  客户端通过调用远程Java程序的方法,调用服务端的一段Java程序(参考:http://bbs.justep.com/forum.php?mod=viewthread&tid=11264)
  服务端的Java程序再调用dll动态连接库
回复

使用道具 举报

 楼主| 发表于 2008-1-2 10:22:42 | 显示全部楼层

Delphi写的动态连接库

library HelloWorldDll;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

uses
  SysUtils,
  Classes;

{$R *.res}

function HelloWorld(UserName: String): String; stdcall;
begin
  Result := 'Hello World, '+UserName+'!';
end;

exports
  HelloWorld;
  
begin
end.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-1-2 10:23:51 | 显示全部楼层

Java调用动态连接库

package com.justep.test;

public class HelloWorldDll {
    static {
        System.loadLibrary("HelloWorldDll");
    }
    public native String HelloWorld(String UserName);
    public static void main(String[] args){
            HelloWorldDll dll = new HelloWorldDll();
            System.out.println(dll.HelloWorld("alang"));
    }
}
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-1-2 10:25:40 | 显示全部楼层
3楼的HelloWorld函数需要真实的函数名是
Java_Package名_Class名_函数名
例如上述函数需要在动态库中增加一个函数来转调
函数名为  Java_com_justep_test_HelloWorldDll_HelloWorld
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-1-2 10:26:10 | 显示全部楼层

修改后的Delphi动态连接库

library HelloWorldDll;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

uses
  SysUtils,
  Classes,
  JNI in 'JNI.pas';

{$R *.res}

function HelloWorld(UserName: String): String; stdcall;
begin
  Result := 'Hello World, '+UserName+'!';
end;

function Java_com_justep_test_HelloWorldDll_HelloWorld(PEnv: PJNIEnv; Obj: JObject; UserName: JString): JString; stdcall;
var
  JVM: TJNIEnv;
  AUser: String;
begin
  JVM:= TJNIEnv.Create(PEnv);
  try
    AUser := JVM.UnicodeJStringToString(UserName);
    Result := JVM.NewStringUTF(PChar(HelloWorld(AUser)));
  finally
    JVM.Free;
  end;
end;

exports
  HelloWorld,
  Java_com_justep_test_HelloWorldDll_HelloWorld;
  
begin
end.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-1-2 10:28:32 | 显示全部楼层
此时,运行3楼的main函数已经可以调用动态库得到调用结果了
现在需要把3楼的类包装成war,这样就可以在客户端调用了,包装方法参考 http://bbs.justep.com/forum.php?mod=viewthread&tid=11264)
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-1-2 10:30:49 | 显示全部楼层
以下是完整的源代码:
  Delphi写的函数源代码

dllsrc.rar

13.27 KB, 下载次数: 115

回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-1-2 10:33:16 | 显示全部楼层
Java源代码,可以放到Eclipse的workspace目录下,直接使用

javasrc.rar

3.52 KB, 下载次数: 178

回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-1-2 10:35:22 | 显示全部楼层
平台上调用代码:
先引入 系统空间\系统运行库\Hessian远程调用

uses
  HessianRPC;
procedure TMainForm.Button3Click(Sender: TObject);
var
  FServer: THessianSever;
begin
  FServer := THessianSever.Create('http://127.0.0.1:8081/HelloWorld/');
  Dialogs.Showmessage(ObjectHelper.ToString(FServer.Call('HelloWorld', ['alang'])));
end;
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-1-2 10:58:54 | 显示全部楼层

如果服务端是linux或者Unix

如果服务端是Linux或者Unix,上述做法也是同样有效的,只是函数库不是dll函数库了,而是.so文件了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Justep Inc.

GMT+8, 2025-7-4 14:05 , Processed in 0.053712 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表