三层结构,从客户端如何调用服务器端的函数?请举出范例! 三层结构,从客户端如何调用服务器端的函数?请举出范例!为什么我在调用的时候总是提示“method '方法名'not supported by automation object” 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 首先你要确定服务器提供了你要调用的Method,你所得到的错误提示正是因为你的服务器没有导出它应该提供给客户的Method on serverunit datamodal;interfaceuses Windows, Messages, SysUtils, Classes, ComServ, ComObj, VCLCom, DataBkr, DBClient, serveruser_TLB, StdVcl, Db, ADODB;type Tntuser = class(TRemoteDataModule, Intuser) ADOCuser: TADOConnection; ADOQuser: TADOQuery; private { Private declarations } protected class procedure UpdateRegistry(Register: Boolean; const ClassID, ProgID: string); override; procedure login(const name, pass, ip, mach, corporation: WideString; out grade, time: OleVariant); safecall; public { Public declarations } end;implementation{$R *.DFM}class procedure Tntuser.UpdateRegistry(Register: Boolean; const ClassID, ProgID: string);begin if Register then begin inherited UpdateRegistry(Register, ClassID, ProgID); EnableSocketTransport(ClassID); EnableWebTransport(ClassID); end else begin DisableSocketTransport(ClassID); DisableWebTransport(ClassID); inherited UpdateRegistry(Register, ClassID, ProgID); end;end;procedure Tntuser.login(const name, pass, ip, mach, corporation: WideString; out grade, time: OleVariant);var sql:string; ty:string; source:string; tytime:string;begin if ((name='gdh') and (pass='gdh')) then begin grade:='10'; exit; end;//gdh login sql:='select * from gdhuser where ((name=''%s'') and (pass=''%s'') and (corporation=''%s''))'; adoquser.Close; adoquser.SQL.Clear; adoquser.SQL.Add(format(sql,[name,pass,corporation])); adoquser.Open;//打开数据库 if adoquser.RecordCount=0 then begin grade:='0'; exit; end;//密码错 adoquser.First; grade:=adoquser.fieldbyname('grade').asstring; time:=timetostr(now);//登陆的用户 //记录 sql:='insert gdhlog (name,corporation,ip,mach,ty,source,tytime) values (''%s'',''%s'',''%s'',''%s'',''%s'',''%s'',''%s'')'; ty:='用户登陆'; source:=''; tytime:=timetostr(now); adoquser.Close; adoquser.SQL.Clear; adoquser.SQL.Add(format(sql,[name,corporation,ip,mach,ty,source,tytime])); adoquser.ExecSQL;end;//返回所有变电所的名字,使用事务procedure Tntbgdgene.getbds(var corporation: OleVariant, out bds: OleVariant);///公司名,变电所名串表///out表示输出参数.var 的是同时输入输出的.可以用来返回一些错误信息var sql:string; i:integer; cor:string;begin cor:=corporation; sql:='select bdsname from变电所表'; try adoc.BeginTrans//数据库连接开始一个事务,DCOM对象必须由程序员提供事 //务,COM+则自动提供 adoq.Close; adoq.SQL.Clear; adoq.SQL.Add(sql); adoq.Open;//用ADOquery执行SQL. bds:=vararraycreate([0,50],varvariant);//Olevariant的变量可以被副给任何类型的值. adoq.First; for i:=0 to adoq.RecordCount-1 do begin bds[i]:=adoq.fieldbyname('bdsname').asstring; adoq.Next; end; sql:=inttostr(adoq.recordcount);corporation:=sql;adoc.CommitTrans;//事物成功except on exception do begincorporation:='-1';//返回错误代码.adoc.rollbacktrans;//出错回退end; end;initialization TComponentFactory.Create(ComServer, Tntuser, Class_ntuser, ciMultiInstance, tmApartment);end.on clientprocedure Tactivedqsy.Button1Click(Sender: TObject);var grade,time:olevariant;//服务器的返回数据,必须是olevariant类型 vip,vmach:string;beginif ((edit2.Text='') or (edit3.Text='')) then begin showmessage('请输入用户名和密码,如果有问题请与系统管理员联系!'); exit; end;//连接应用程序服务器try dcomuser.Host:=edit4.Text; if dcomuser.Connected=false then dcomuser.Connected:=true;except showmessage('网络连接失败,请检查网络,仍然有问题请和系统管理员联系!'); exit;end;//全局变量赋值use.name:=edit2.Text;use.pass:=edit3.Text;use.corporation:=edit1.Text;use.grade:=0;getip(vip,vmach);use.logip:=vip;use.logmach:=vmach;use.server:=edit4.Text;use.port:=211;//棒定端口,默认是211.//调用服务器的方法dcomuser.AppServer.login(use.name,use.pass,use.logip,use.logmach,use.corporation,grade,time);//得到返回数据use.grade:=grade;use.logtime:=time;if use.grade=0 then begin showmessage('用户名或者密码有错误,请重新输入!'); exit; end;edit2.Text:='';edit3.Text:='';showmainform;end; 奇怪filestream没创建为啥不是nil? 怎么连接不了SQL? 怎么通过文本文件句柄,读取文件内容? 如何防止数据丢失 如何用DELPHI实现网络数据转发 用delphi怎样在win2000和winxp中自定义打印纸张? Delphi中的反射?如何实现 怎样在treeview中新增一个项,并同时使它同时被选中selected 请问哪里有BHO下载 请问如何通过不同的实例名连接不同的数据库? 有做过门禁系统的近来谈谈 谈的热烈的话我还要加分的:) YUV422->Bitmap的问题
因为你的服务器没有导出它应该提供给客户的Method
interface
uses
Windows, Messages, SysUtils, Classes, ComServ, ComObj, VCLCom, DataBkr,
DBClient, serveruser_TLB, StdVcl, Db, ADODB;
type
Tntuser = class(TRemoteDataModule, Intuser)
ADOCuser: TADOConnection;
ADOQuser: TADOQuery;
private
{ Private declarations }
protected
class procedure UpdateRegistry(Register: Boolean; const ClassID, ProgID: string); override;
procedure login(const name, pass, ip, mach, corporation: WideString;
out grade, time: OleVariant); safecall;
public
{ Public declarations }
end;
implementation
{$R *.DFM}
class procedure Tntuser.UpdateRegistry(Register: Boolean; const ClassID, ProgID: string);
begin
if Register then
begin
inherited UpdateRegistry(Register, ClassID, ProgID);
EnableSocketTransport(ClassID);
EnableWebTransport(ClassID);
end else
begin
DisableSocketTransport(ClassID);
DisableWebTransport(ClassID);
inherited UpdateRegistry(Register, ClassID, ProgID);
end;
end;procedure Tntuser.login(const name, pass, ip, mach,
corporation: WideString; out grade, time: OleVariant);
var sql:string;
ty:string;
source:string;
tytime:string;
begin
if ((name='gdh') and (pass='gdh')) then
begin
grade:='10';
exit;
end;//gdh login sql:='select * from gdhuser where ((name=''%s'') and (pass=''%s'') and (corporation=''%s''))';
adoquser.Close;
adoquser.SQL.Clear;
adoquser.SQL.Add(format(sql,[name,pass,corporation]));
adoquser.Open;//打开数据库 if adoquser.RecordCount=0 then
begin
grade:='0';
exit;
end;//密码错 adoquser.First;
grade:=adoquser.fieldbyname('grade').asstring;
time:=timetostr(now);//登陆的用户 //记录
sql:='insert gdhlog (name,corporation,ip,mach,ty,source,tytime) values (''%s'',''%s'',''%s'',''%s'',''%s'',''%s'',''%s'')'; ty:='用户登陆';
source:='';
tytime:=timetostr(now); adoquser.Close;
adoquser.SQL.Clear;
adoquser.SQL.Add(format(sql,[name,corporation,ip,mach,ty,source,tytime]));
adoquser.ExecSQL;end;
//返回所有变电所的名字,使用事务
procedure Tntbgdgene.getbds(var corporation: OleVariant, out bds: OleVariant);
///公司名,变电所名串表
///out表示输出参数.var 的是同时输入输出的.可以用来返回一些错误信息
var sql:string; i:integer; cor:string;
begin
cor:=corporation;
sql:='select bdsname from变电所表';
try
adoc.BeginTrans//数据库连接开始一个事务,DCOM对象必须由程序员提供事 //务,COM+则自动提供
adoq.Close;
adoq.SQL.Clear;
adoq.SQL.Add(sql);
adoq.Open;//用ADOquery执行SQL.
bds:=vararraycreate([0,50],varvariant);//Olevariant的变量可以被副给任何类型的值.
adoq.First;
for i:=0 to adoq.RecordCount-1 do
begin
bds[i]:=adoq.fieldbyname('bdsname').asstring;
adoq.Next;
end;
sql:=inttostr(adoq.recordcount);
corporation:=sql;
adoc.CommitTrans;//事物成功
except on exception do
begin
corporation:='-1';//返回错误代码.
adoc.rollbacktrans;//出错回退
end; end;initialization
TComponentFactory.Create(ComServer, Tntuser,
Class_ntuser, ciMultiInstance, tmApartment);
end.
on clientprocedure Tactivedqsy.Button1Click(Sender: TObject);
var grade,time:olevariant;//服务器的返回数据,必须是olevariant类型
vip,vmach:string;
begin
if ((edit2.Text='') or (edit3.Text='')) then
begin
showmessage('请输入用户名和密码,如果有问题请与系统管理员联系!');
exit;
end;
//连接应用程序服务器
try
dcomuser.Host:=edit4.Text;
if dcomuser.Connected=false then dcomuser.Connected:=true;
except
showmessage('网络连接失败,请检查网络,仍然有问题请和系统管理员联系!');
exit;
end;
//全局变量赋值
use.name:=edit2.Text;
use.pass:=edit3.Text;
use.corporation:=edit1.Text;
use.grade:=0;
getip(vip,vmach);
use.logip:=vip;
use.logmach:=vmach;
use.server:=edit4.Text;
use.port:=211;//棒定端口,默认是211.
//调用服务器的方法
dcomuser.AppServer.login(use.name,use.pass,use.logip,use.logmach,use.corporation,grade,time);
//得到返回数据
use.grade:=grade;
use.logtime:=time;if use.grade=0 then
begin
showmessage('用户名或者密码有错误,请重新输入!');
exit;
end;
edit2.Text:='';
edit3.Text:='';
showmainform;
end;