1,考虑到软件开发过程中有些功能函数或业务逻辑不想放在客户端,如单据流水号的生成,核心算法;可将此功能代码封装在DLL里面,编译后以插件的形式放在服务端,然后客户端通过固定的接口函数调用,结果会以OleVariant类型返回;简单灵活易用。
服务器DLL模板格式:
unit ETU.Demo;
interface
uses
SysUtils, Windows, Messages, dbclient, Classes, Dialogs, IPlugin, midasLib;
{
//IBPlugin为继承的接口类
}
type
TETUTestdll = class(TInterfacedObject, IBPlugin)
private
tcpFun: HWND;
// 业务处理
function getdbData(out resultData: OleVariant; out sErrorMsg: string): boolean;
protected
public
ci: integer;
CC: string;
// 对象构造方法
constructor create(const paramStr: string);
destructor Destory;
{
//dll 入口函数: 不可改变名称与参数
paramStr: 参入的json格式的参数字符串 或普通字符串,只要客户端与服务端一直即可
resultData:返回 OleVariant 类型的接口(可以是普通字符串,数值,json 格式的字符串,clientDataset.data 数据集
等)
sErrorMsg: 返回错误信息
result:成功返回true
}
function MainMethod(const paramStr: string; out resultData: OleVariant; out sErrorMsg: string): boolean;
end;
implementation
{
//若需调用中间层的方法 tcpFun.dll :封装对应的中间层方法
(顺序: 连接服务器->操作对应的方法->断开连接)
}
// 连接中间服务器
function setSQLConnection(out sErrorMsg: string): boolean; stdcall; external 'tcpFun.dll';
// 执行sql语句
function ExecSqlText(cds: TClientDataSet; sSqlText: string; DBType: string; haveResult: boolean; out sErrorMsg: string): boolean; stdcall; external 'tcpFun.dll';
// 断开服务器连接
function DisSQLConnection(out sErrorMsg: string): boolean; stdcall; external 'tcpFun.dll';
constructor TETUTestdll.create(const paramStr: string);
var
sErrorMsg: string;
begin
inherited create();
end;
destructor TETUTestdll.Destory;
begin
inherited;
end;
function TETUTestdll.getdbData(out resultData: OleVariant; out sErrorMsg: string): boolean;
var
i: double;
cds: TClientDataSet;
sSqlText: string;
begin
result := false;
if not setSQLConnection(sErrorMsg) then
raise Exception.create(sErrorMsg);
try
cds := TClientDataSet.create(nil);
try
sSqlText := 'select top 11 * from stundent';
result := ExecSqlText(cds, sSqlText, '1', true, sErrorMsg);
if not result then
raise Exception.create(sErrorMsg);
resultData := cds.Data;
finally
FreeAndNil(cds);
end;
finally
DisSQLConnection(sErrorMsg);
end;
end;
function TETUTestdll.MainMethod(const paramStr: string; out resultData: OleVariant; out sErrorMsg: string): boolean;
begin
try
result := getdbData(resultData, sErrorMsg);
except
on ee: Exception do
begin
sErrorMsg := ee.Message;
end;
end;
end;
end.
IBPlugin 接口单元(引用即可无需修改):
unit IPlugin;
interface
uses Windows;
type
IBPlugin = interface (IInterface)
['{FA895923-9826-4249-B9E7-A5D0F1CF758D}']
//声明一个方法
function MainMethod(const paramStr: string; out resultStr:OleVariant;out sErrorMsg: string):boolean;
end;
type
TPluginProperty = record
objClass: IBPlugin; //DLL对应的对象
objhandle: cardinal; //句柄
token: string; //访问秘钥
loadtype: string; //调用方式
filepath: string; //dll文件路径
end;
//对象创建,可以传入一个参数
type
TCreateObject = function(const paramStr: string): IBPlugin; stdcall;
implementation
end.
编译后复制DLL 文件到服务端的插件目录【Plugin】,然后在服务器页面设置插件信息:
客户端调用:
{
--------说明:-----------
PluginMethod(fileid: string; Token: string; paramStr: string; ouresultData:OleVariant; out sErrorMsg: string): Boolean;
PluginMethod :调用DLL接口函数
fileid: DLL对应的ID
Token: 调用秘钥
paramStr: 传入的参数(与dll插件类型一致:普通字符串或json格式)
ouresultData:返回的结果
}
//例如:
procedure TFclient.Button1Click(Sender: TObject);
var
sErrorMsg: string;
vData: OleVariant;
begin
if ser.PluginMethod('1', '123', '', vData, sErrorMsg) then
CDS1.Data:=vData
else
showmessage(sErrorMsg);
end;