三层结构,从客户端如何调用服务器端的函数?请举出范例!
为什么我在调用的时候总是提示“method '方法名'not supported by automation object”

解决方案 »

  1.   

    首先你要确定服务器提供了你要调用的Method,你所得到的错误提示正是
    因为你的服务器没有导出它应该提供给客户的Method
      

  2.   

    on serverunit datamodal;
    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;