谈谈:COM、DCOM、COM+ 中如何避免“灾难性故障”。(100分)

  • 主题发起人 主题发起人 darnis
  • 开始时间 开始时间
D

darnis

Unregistered / Unconfirmed
GUEST, unregistred user!
做COM、DCOM、COM+ 应用的时候,老是爱出现“灾难性故障”
大虾们谈谈,在写这类应用的时候要注意些什么?
又怎样来调试一个 “In-Process” 类型的COM服务器?
 
我最近也碰到过这样的情况,发现问题主要是没有建立Com对象,
应该在初始化时建立,如
var
FrdmClientsFactory:TComponentFactory;
在初始化段加入:
FrdmClientsFactory:=.....
 
我现在实际上是做的,, OleAutomation,,

在每个类的实现类文件里都有

initialization
TAutoObjectFactory.Create(ComServer, TSender, Class_Sender,
ciMultiInstance, tmApartment);

这种类似的语句,,
你的意思,,要建立一个全局的 COM对象,,让所有的访问都连接到一个实例上啊?

那COM的本质有没有影响呢?
 
哦,我是在使用共享连接时,遇到的情况处理,其中子RDM的Instancing是使用Internal方式,所以在初始化段是这样的:
initialization
FrdmFactory:=TAutoObjectFactory.Create(ComServer, TSender, Class_Sender,
ciInternal, tmApartment);
不知你是在什么情况下遇到这样的问题?
 
我遇到的“灾难性故障”这个问题有点奇怪,
我调用一次接口函数没有问题,,第二次调用同样一个接口函数(这里的第二次调用不是下面代码中的那个第二调用),就出现问题了,,

这个“灾难性故障”跟COM对象的实例形式有关系吗?

还有我在COM服务端,有些个接口跟Word 的多文档方式差不多,就是需要有多个相同的接口, 实际上我是用一个 TList 来保存接口,但是问题比较多,不知道我的方式对不对?

var
i, sum: integer;
tmp: IArea;
begin
///////////////////////////////////////////////
// 检查可用的显示区域。。
sum := 0;
for i := 0 to FAreaList.Count -1 do // 第一次加入没有问题,第二次 AddArea
// 时,, FAreaList.Items 是有效的地址值,强制转换成
// IArea 时老出错,反映到客户端时就是“灾难性故障”
// 后来我把 FAreaList 改成 array of IArea 后修改相应的代码
// 这里不会出错了,但是调用其它的接口函数,比如后面的
begin
sum := sum + IArea(FAreaList.Items).Size;
end;

// 保证加入的显示区域在屏体有效范围内。
ACol := Min(ACol, FColCount - sum);
//////////////////////////////////////////////
if ACol <= 0 then
raise EDispAreaError.Create('没有可用的显示区分配空间');
///////////////////
// 在所有显示区的最末加入显示区。


tmp := TArea.Create(self, Get_AreaCount);
tmp.Size := ACol;

tmp.Start := sum + COL_START;
tmp.Size := ACol;

FAreaList.Add(TArea(tmp));
Result := tmp;

end;

下面这个过程是在修改成 FArealist 成 array of IArea ,上一个函数正常后,调用像下面这样的接口老是在第一次调用正常后,再调用就出现“灾难性故障”

function TLEDTPSvr.StopShow: Integer;
var
cTmp: PChar;
strTmp: string;
len: integer;
begin
FCmdMaker.Command := CMD_STOP;

strTmp := FCmdMaker.Output;

len := Length(strTmp);
GetMem(cTmp, len);
Move(PChar(strTmp)^, PChar(cTmp)^, len);
result := FSender.SendData(cTmp, len);
end;


基本的东西,了解得不是很透彻,现在遇到这样子的问题都不知道该怎么来做了,:O

还有我的这个COM Server 是"In-process"类型的,该怎么来调试啊?我现在是只有加 Showmessage 来看,加看来的结果是在调用结束后,返回的过程中出现的错误。。

………………
 
大虾们说一下,,平常调试像 DLL 这样子的程序是怎么调试的啊!!
我真的是笨到极点啦 ,,,搞不懂有什么好的方式,,,
如果可以单步跟踪到DLL里就好了,,,,,,
 
问题解决,,

总结如下:

在创建具有层次关系的COM Server

比如
APP
|-Sender -----
| |- 属性1
| |- 属性2
| |- 属性3
| |- ....
|-Areas --
| |- 属性1
| |- 属性2
| |- 属性3
| |- ....
|-属性
|-.....

在 App 里对 Area 和Sender的管理上,不能直接用Area和Sender的实现类来管理,
应该使用 Area和Sender 相应的接口(IArea, ISender)来管理,
不然容易出现一些莫名的异常,反应到客户端,就是“灾难性故障”了。

大虾们都谈谈经验啊。。!
小弟我是初次做COM哦,,想学习,,但是没有几个热心人。。。
:((
 
做一个简单的应用程序 调用你的com的方法

在com的工程中的运行参数中选择你的应用程序

点执行 就可以单步调试了
 
谢谢指点哦,,我先试试。。。
 
但是跟不进去啊?
 
你设置断点没有 要执行com的工程

应用程序作为参数 当然应用程序要调用com中提供的方法
 
现在知道怎么一回事了,,

COM工程设置里的 Linker 页里的
EXE and DLL Options
内的
Include remote debug symbols 选上,
编译后,
Run Parameters 的 Host Application 值设为调用COM对象的EXE文件就可以了。。
 
多人接受答案了。
 
后退
顶部