关于APPSERVER的调用问题?(50分)

  • 主题发起人 主题发起人 kinn_liu
  • 开始时间 开始时间
K

kinn_liu

Unregistered / Unconfirmed
GUEST, unregistred user!
各位大虾:
我在应用服务器端定义了一个方法 GETNAME ,
定义是这样的:
HRESULT _stdcall getname([in, out] VARIANT * name );
实现是这样的
procedure Ttest.getname(var name: OleVariant);
begin
name := 'OK';
end;
可是,我在客户端(客户端也在本机上)调用时,即 DCOMConnection1.AppServer.getname(name);
出现异常,错误提示为
......EOLESYSERROR WITH MESSAGE '接线者无效'.......
不知道为什么?
 
这个问题是简单还是复杂,怎么没人看呀?
 
没有做过.我记得有一个midas数据库demo里面有一个例子,你可以看看.
 
“接线者无效”---
会不会是DCOM的权限没设好呢?
瞎猜的。 :)
 
谢谢weck.
我看了那个例子,它是把参数作为返回值,回传给client的,我照着例子改了一下,就好了
可是我想用参数的引用方式传值的话,就是说我想利用 parameter flag 被我定义成out
的参数传值,可以吗?
parameter flag究竟是应该怎样定义呢?
望大虾指点...
可以附加分数.
 
当然可以了 只是你应该分别定义输入参数和输出参数而已
例子如下:
...................
[id(0x00000001)]
HRESULT _stdcall getuser([in] VARIANT * loguser, [out] VARIANT * admin );
..................
procedure Tlppgp0001.getuser(var loguser: OleVariant;
out admin: OleVariant);
begin
//定义处理过程....
end;

在客户端定义变量loguser admin ........
loguser :=......... //loguser 必须在调用前初始化 admin 可以不初始化
.........
DCOMConnection1.AppServer.getuser(loguser,admin);
admin 即是传输回来的值
 
to ppppgp :
谢谢,
可是我一丝不苟的照作了,可是还是出现那个异常,好像没有说到点子上呀...
 
到底是dcom权限设置的问题,还是程序中参数类型设置不对
哎,反正有点摸不到头脑,那位大虾能指点一二...
wait.....
 
设置问题dcom
 
to autumn:
请大虾明示
 
本来想把我的实验例子源代码贴上的 但是太大了 只说一下步骤吧
事实上我参考的例子是 Demos/Midas/Login 里面的服务器上的
login 函数 它的原形是
[id(0x00000002)]
HRESULT _stdcall Login(BSTR UserName, BSTR Password );

我只是改写了它的两个参数的类型而已 我是通过直接修改 server.tlb
实现的 你再试一试吧 不行 我把 源码发给你????

再问一下 你是通过什么来定义的 直接修改代码文件 ?还是 通过IDE ???
 
请发给我吧
谢谢.
我就是用type library edit定义的.
是不是dcom需要额外的设置呀?
 
给个示例你,对比一下看是否有参考价值
SERVER:
unit uIServer;
interface
uses
Windows, Messages, SysUtils,
Classes, ComServ, ComObj,
VCLCom, DataBkr,DBClient,
PIServer_TLB, StdVcl, Db, DBTables, Provider;
type
TIServer = class(TRemoteDataModule, IIServer)
Table1: TTable;
DataSetProvider1: TDataSetProvider;
private
{ Private declarations }
protected
//class procedure UpdateRegistry(Register: Boolean;
const ClassID, ProgID: string);
override;
// function Get_Country: IProvider;
safecall;
procedure login(const User, Password: WideString);
safecall;
procedure Logout(const User: WideString);
safecall;
public
{ Public declarations }
end;
var
server: TIserver ;
implementation
uses fIServer;
{$R *.DFM}
{class procedure TIServer.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;
}
//function TIServer.Get_Country: IProvider;
//begin
// Result:=Table1.Provider;
//end;

procedure TIServer.login(const User, Password: WideString);
begin
form1.listbox1.items.addobject(user,tstringstream.create(password));
end;

procedure TIServer.Logout(const User: WideString);
begin
with Form1.Listbox1do
begin
(Items.Objects[Items.IndexOf(User)]).free;
Items.Delete(Items.IndexOf(User));
end;
end;

initialization
TComponentFactory.Create(ComServer, TIServer,
Class_IServer, ciMultiInstance, tmApartment);
end.
SERVER FORM
unit fIServer;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
ListBox1: TListBox;
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
{$R *.DFM}
end.
CLIENT
LOGIN FORM
unit Unit1;
interface
uses Windows, SysUtils, Classes, Graphics, Forms, Controls, StdCtrls,
Buttons, ExtCtrls;
type
TDlg1 = class(TForm)
OKBtn: TButton;
CancelBtn: TButton;
Bevel1: TBevel;
Label1: TLabel;
Label2: TLabel;
Edit1: TEdit;
Edit2: TEdit;

private
{ Private declarations }
public
{ Public declarations }
end;

var
Dlg1: TDlg1;
implementation
{$R *.DFM}

end.
MAIN FORM
unit DataFrm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Db, DBClient, MConnect, Grids, DBGrids, StdCtrls;
type
TForm2 = class(TForm)
Button1: TButton;
DBGrid1: TDBGrid;
DCOMConnection1: TDCOMConnection;
ClientDataSet1: TClientDataSet;
DataSource1: TDataSource;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
User: wideString;
FLogin: Boolean;
public
{ Public declarations }
end;

var
Form2: TForm2;
implementation
uses Unit1;
{$R *.DFM}
procedure TForm2.FormCreate(Sender: TObject);
begin
flogin:= false;
end;

procedure TForm2.Button1Click(Sender: TObject);
var
password: string;
begin
if not(flogin) then
begin
if Dlg1.showModal=mrok then
begin
flogin:= true;
user:= Dlg1.edit1.text;
password:= Dlg1.edit2.text;
dcomconnection1.AppServer.login(user,password);
end;
end;
clientdataset1.Open;
end;

end.
 
各位大虾,小弟现在出现的问题是:当我把parameter flag设成out时,在client中调用
appserver.函数名(...)时就出现异常:'接线者无效',其他都是正常的.
rax兄提供的例子我运行也是正常的.
rax,你能把参数设成out,用这个参数传递一下值,看看可以吗?
 
我试了可以,源码再给你
SERVER
unit uIServer;
interface
uses
Windows, Messages, SysUtils,
Classes, ComServ, ComObj,
VCLCom, DataBkr,DBClient,
PIServer_TLB, StdVcl, Db, DBTables, Provider;
type
TIServer = class(TRemoteDataModule, IIServer)
Table1: TTable;
DataSetProvider1: TDataSetProvider;
private
{ Private declarations }
protected
procedure login(var User, Password: WideString);
safecall;
procedure Logout(const User: WideString);
safecall;
public
{ Public declarations }
end;
var
server: TIserver ;
implementation
uses fIServer;
{$R *.DFM}
{class procedure TIServer.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;
}
//function TIServer.Get_Country: IProvider;
//begin
// Result:=Table1.Provider;
//end;

procedure TIServer.login(var User, Password: WideString);
begin
form1.listbox1.items.addobject(user,tstringstream.create(password));
end;

procedure TIServer.Logout(const User: WideString);
begin
with Form1.Listbox1do
begin
(Items.Objects[Items.IndexOf(User)]).free;
Items.Delete(Items.IndexOf(User));
end;
end;

initialization
TComponentFactory.Create(ComServer, TIServer,
Class_IServer, ciMultiInstance, tmApartment);
end.
unit PIServer_TLB;
// ************************************************************************ //
// WARNING
// -------
// The types declared in this file were generated from data read from a
// Type Library. If this type library is explicitly or indirectly (via
// another type library referring to this type library) re-imported, or the
// 'Refresh' command of the Type Library Editor activated while editing the
// Type Library, the contents of this file will be regenerated and all
// manual modifications will be lost.
// ************************************************************************ //
// PASTLWTR : $Revision: 1.88.1.0.1.0 $
// File generated on 2000-8-21 11:55:08 from Type Library described below.
// ************************************************************************ //
// Type Lib: F:/delphistudy/s15_4/server/PIServer.tlb (1)
// IID/LCID: {D751F2D1-8790-4765-A9FF-9E51655FFE64}/0
// Helpfile:
// DepndLst:
// (1) v1.0 Midas, (C:/WINNT/System32/midas.dll)
// (2) v2.0 stdole, (C:/WINNT/System32/stdole2.tlb)
// (3) v4.0 StdVCL, (C:/WINNT/System32/STDVCL40.DLL)
// ************************************************************************ //
{$TYPEDADDRESS OFF} // Unit must be compiled without type-checked pointers.
interface
uses Windows, ActiveX, Classes, Graphics, OleServer, OleCtrls, StdVCL,
MIDAS;
// *********************************************************************//
// GUIDS declared in the TypeLibrary. Following prefixes are used:
// Type Libraries : LIBID_xxxx
// CoClasses : CLASS_xxxx
// DISPInterfaces : DIID_xxxx
// Non-DISP interfaces: IID_xxxx
// *********************************************************************//
const
// TypeLibrary Major and minor versions
PIServerMajorVersion = 1;
PIServerMinorVersion = 0;
LIBID_PIServer: TGUID = '{D751F2D1-8790-4765-A9FF-9E51655FFE64}';
IID_IIServer: TGUID = '{137FF133-27FE-49D5-8321-2C0BC2A22BD3}';
CLASS_IServer: TGUID = '{EF58EF41-CA50-4DA9-A825-3DBB0E7352D6}';
type
// *********************************************************************//
// Forward declaration of types defined in TypeLibrary
// *********************************************************************//
IIServer = interface;
IIServerDisp = dispinterface;
// *********************************************************************//
// Declaration of CoClasses defined in Type Library
// (NOTE: Here we map each CoClass to its Default Interface)
// *********************************************************************//
IServer = IIServer;

// *********************************************************************//
// Interface: IIServer
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {137FF133-27FE-49D5-8321-2C0BC2A22BD3}
// *********************************************************************//
IIServer = interface(IAppServer)
['{137FF133-27FE-49D5-8321-2C0BC2A22BD3}']
procedure login(var User: WideString;
var Password: WideString);
safecall;
procedure Logout(const User: WideString);
safecall;
end;

// *********************************************************************//
// DispIntf: IIServerDisp
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {137FF133-27FE-49D5-8321-2C0BC2A22BD3}
// *********************************************************************//
IIServerDisp = dispinterface
['{137FF133-27FE-49D5-8321-2C0BC2A22BD3}']
procedure login(var User: WideString;
var Password: WideString);
dispid 1;
procedure Logout(const User: WideString);
dispid 2;
function AS_ApplyUpdates(const ProviderName: WideString;
Delta: OleVariant;
MaxErrors: Integer;
out ErrorCount: Integer;
var OwnerData: OleVariant): OleVariant;
dispid 20000000;
function AS_GetRecords(const ProviderName: WideString;
Count: Integer;
out RecsOut: Integer;
Options: Integer;
const CommandText: WideString;
var Params: OleVariant;
var OwnerData: OleVariant): OleVariant;
dispid 20000001;
function AS_DataRequest(const ProviderName: WideString;
Data: OleVariant): OleVariant;
dispid 20000002;
function AS_GetProviderNames: OleVariant;
dispid 20000003;
function AS_GetParams(const ProviderName: WideString;
var OwnerData: OleVariant): OleVariant;
dispid 20000004;
function AS_RowRequest(const ProviderName: WideString;
Row: OleVariant;
RequestType: Integer;
var OwnerData: OleVariant): OleVariant;
dispid 20000005;
procedure AS_Execute(const ProviderName: WideString;
const CommandText: WideString;
var Params: OleVariant;
var OwnerData: OleVariant);
dispid 20000006;
end;

// *********************************************************************//
// The Class CoIServer provides a Create and CreateRemote method to
// create instances of the default interface IIServer exposed by
// the CoClass IServer. The functions are intended to be used by
// clients wishing to automate the CoClass objects exposed by the
// server of this typelibrary.
// *********************************************************************//
CoIServer = class
class function Create: IIServer;
class function CreateRemote(const MachineName: string): IIServer;
end;

implementation
uses ComObj;
class function CoIServer.Create: IIServer;
begin
Result := CreateComObject(CLASS_IServer) as IIServer;
end;

class function CoIServer.CreateRemote(const MachineName: string): IIServer;
begin
Result := CreateRemoteComObject(MachineName, CLASS_IServer) as IIServer;
end;

end.

//[id(0x00000001)]
HRESULT _stdcall login([in, out] BSTR * User, [in, out] BSTR * Password );
CLIENT 无改变
 
各位大虾,小弟现在出现的问题是:当我把parameter flag设成out时,在client中调用
appserver.函数名(...)时就出现异常:'接线者无效',其他都是正常的.
rax兄提供的例子我运行也是正常的.
rax,你能把参数设成out,用这个参数传递一下值,看看可以吗?
 
谢谢 , ppppgp
看来我是没有写对数据类型
设成BTR*就可以了,为什么我设成variant*会出现异常呢?不是说这个类型可以随意用吗?
有空请回答.
 
多人接受答案了。
 
to kinn_liu:
对不起了 因为这几天都没有办法上网的 所以直到现在才看见 本来以为
你已经不需要我的源代码了的 现在看来还是需要??? 我已经把源代码
邮寄给你了 你看看有什么问题没有
没有想到我得了这么多分的 都不好意思了 :-)
当然分数越多越好 :-)
设成 variant* 也绝对可以的
事实上 当使用 IDE 方式的 TLB 管理者的工具条 New Method 按钮
添加的函数或者过程 只要正确设置 所有基本代码都是自动添加的
只需要到定义处 添加处理代码就可以了的呀
在管理者中选定函数或者过程 在它右边可以看见parameters 面板
里面有name、Type、Modifier
Type 是下拉式选择的 当选择 VARIANT * 时
服务器方自动定义参数为 OleVariant 类型
Modifer 即 parameter flags 选择
是可以选择 in 或者 out 的
再试一试吧

 
后退
顶部