大家帮我搞定这个问题吧--绝对有意思的对象间调用(再线等待) ( 积分: 100 )

  • 主题发起人 主题发起人 zhang214
  • 开始时间 开始时间
Z

zhang214

Unregistered / Unconfirmed
GUEST, unregistred user!
我现在创建了一个 THDCot_IntF = class(TWebModule) web窗体,然后这里边放一些控件,想在另一个继承自莫接口的类(THDCOT_EC = class(TInvokableClass, IHDCOT_EC))中调用THDCot_IntF中的控件值之类的东西。编译通过,但是程序执行时报错。(IHDCOT_EC为
我自己定义的接口)
我就像实现类似于win32应用程序中在Form1中调用 form2.visible:=true;的功能。不知道问题出在那里?希望高手指点。
自我认为是两个类继承自不同的类。调用就不能如同窗体间的调用(这是一个web应用程序)。
 
我现在创建了一个 THDCot_IntF = class(TWebModule) web窗体,然后这里边放一些控件,想在另一个继承自莫接口的类(THDCOT_EC = class(TInvokableClass, IHDCOT_EC))中调用THDCot_IntF中的控件值之类的东西。编译通过,但是程序执行时报错。(IHDCOT_EC为
我自己定义的接口)
我就像实现类似于win32应用程序中在Form1中调用 form2.visible:=true;的功能。不知道问题出在那里?希望高手指点。
自我认为是两个类继承自不同的类。调用就不能如同窗体间的调用(这是一个web应用程序)。
 
我说的不清楚吗?要是大家不明白我的问题,可以指出,我来说明....
 
你如果在THDCOT_EC中调用调用THDCot_IntF中的东西,必须创建THDCot_IntF的对象啊
win32中Form1,Form2都是TForm类的对象
在类中只能调用它的父类和它的成员中的东西
欢迎讨论!
 
创建对像的方法是可以的,但是我现在不想每次都创建THDCot_IntF,因为这个类会在服务启动时自己创建,然后我想在这里边放一个我自己的线程管理类,THDCOT_EC 中的方法,调用THDCot_IntF线程管理类提供的TsqlConnection对象。
如果改为每次创建THDCot_IntF 我的线程管理类就没有用了。希望指点,或者换个思路也行。
 
没有遇到过这样的问题
那样的话只能继承THDCot_IntF类或者它的父类,因为你用到了他的方法
 
或者问大家这样一个问题:
我的 类如何从 两个类一个接口继承下来 TTest= class(TWebModule ,TInvokableClass,, IHDCOT_EC)
,这就是所谓的多继承吧,好像d只支持单继承,我怎样才能搞出从上边这两个类+一个接口继承的产物?这个可能比较容易吧。估计就是吧一个类转化为接口,然后再实现2个接口+1个类,估计就行了,
理论如此,但是实现方面还需要大家指点。
 
这样实现很困难吗?大家没有碰上过这种问题吗?
 
你的想法很正确,实现也不困难。如果实现接口的对象已经在内存中建立了,你需要做的工作就是利用QueryInterface得到正确的对象指针。

虽然接口这个词听起来很神秘,也确实存在一些技巧和思想,但假如你把它简单地看成某个类的操作的暴露,一切就变得相当平顺了,祝好运。
 
flamingo说得对
 
说的云里雾里的,不过我好像有点感觉了,我需要的就是flamingo所说的东西,去内存中找到以前创建的对象指针,然后就为所欲为了。这玩艺还是瞒爽的,等我试好了后就来散
分。
 
欢迎大家继续讨论,来者有分
 
同志们,我的问题正如 flamingo 说的那种方法可以解决。但是还有一点问题就是,接口实现类中的某些方法(function)可以调用成功,有些却不行?不知道为啥原因? 我把代码贴出来大家看一下。
自己定义的接口
IMyTest = interface(Iinterface)
['{542CC350-E825-407E-BC71-B1D92FB5725F}']
function test:string;
function AcquireSQLCon: TMyConnection;
procedure ReleaseSQLCon(SQLCon: TMyConnection);
接口实现类
TMyConnectionPool = class(TComponent,IMyTest)
private
FSQLConList: TThreadList;
FInUseList: TBits;
FMaxConnections: Integer;//=10
FServerName: string;
FUserName: string;
FPassword: string;
FSQLConTemplate: TSQLConnection;
procedure SetMaxConnections(const Value: Integer);
procedure SetServerName(const Value: string);
procedure SetUserName(const Value: string);
procedure SetPassword(const Value: string);
protected
public
constructor Create(AOwner: TComponent)
override;
destructor Destroy
override;
procedure OpenAll;
function AcquireSQLCon: TMyConnection;//接口中的方法
procedure ReleaseSQLCon(SQLCon: TMyConnection);//同上
function test:string;// 同上
property MaxConnections: Integer read FMaxConnections write

调用过程如下:
procedure TForm3.Button1Click(Sender: TObject);
var wc :Tobject;
const gid: TGUID = '{542CC350-E825-407E-BC71-B1D92FB5725F}';
var i :Longint;
var s:TMyConnection;
//IMultiModuleSupport = interface
{847EC549-523F-4613-9F02-49FD1CD7F0E0}
begin
//Result := False;
try
i:=QueryInterface(gid,wc);
showmessage((wc as TMyConnectionPool).test);//这句能正确执行
s:=TMyConnection.Create(self);
s:= (wc as TMyConnectionPool).AcquireSQLCon;//这句会报错,而在创建它的窗体里边就不报错。
showmessage('2');
exit;
showmessage(s.EntGid);

finally
(wc as TMyConnectionPool).ReleaseSQLCon(s);
end;
end;

接口方法 test 调用成功,而AcquireSQLCon 调用却不成功,总是提示AccessViolation
At address 004D23A4.
大家献招吧!!!!
 
啊嚏~~~!

这就表示我来了。我告诉你吧。
 
先来看看:
1) i:=QueryInterface(gid,wc);
2) showmessage((wc as TMyConnectionPool).test);//这句能正确执行
3) s:=TMyConnection.Create(self);
4) s:= (wc as TMyConnectionPool).AcquireSQLCon;//这句会报错,而在创建它的窗体里边就不报错。

第四句要出问题了,事实上你已经出问题了。
因为在第二句中,wc 已经是一个接口而不是对象实例了,所以你不能再做一次对象到接口的转换。
 
我去掉第二句也不对呀?
请直接说吧,我是外行...
 
我没有测试,因为我已经不使用Delphi这个鬼语言多年了,下面说的需要你自己去证明:

在第一句获得实现接口的对象指针以后,Delphi会产生一个接口加一动作,
当第二句使用接口转换以后,语句结束,Delphi就释放这个接口,这点Delphi与C++不同。
所以到了第四句,你应该测试一下这个接口指针是否还在,如果不存在了,你就麻烦了,你需要重新找回这个接口才能使用,这也就是很久以前高手们常说的接口和对象模型混合使用的典型现象。
 
我的话完了。因我凭空实在写不出东西了。啊嚏~~~!我走了。
 
我不用as 用下边的语句好像也不对。这块真的想不通了??
s:= TMyConnectionPool(wc).AcquireSQLCon;
 
后退
顶部