请教:进程外com的生存期问题

longagoer 2003-10-24 10:32:36
我自己做了一个进程外com的简单例子:comserver.exe和comclient.exe,然后用两种方法测试:
1.不启动comserver,直接运行comclient的话,在进程管理器里能够看到comserver正在运行,当退出comclient时,comserver也相应的退出了,这些都是正常的。

2.先启动comserver,然后运行comclient的话,进程管理器中仍只有一个comserver进程,这也应该是对的,可是在我退出comclient的时候,发现comserver进程也退出了,按照我自己对com生存期的理解,comserver此时不应该退出的吧?因为它自己的引用计数不是0啊,不知道我理解的对否?各位高手指正,谢谢
...全文
78 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
longagoer 2003-10-25
  • 打赏
  • 举报
回复
哦,我是用atl编写的comserver,但是找不到在哪个函数中添加锁计数器啊,只见到有一个自动生成的UnLock()函数,大侠,帮到底吧,多谢,我可以再添分的,呵呵
lop5712 2003-10-25
  • 打赏
  • 举报
回复
在楼主的CAtlModule派生类中重载PreMessageLoop,在其中先调用父类的PreMessageLoop,再通过GetCommandLine得到命令行,然后解析命令行(如果是MFC,CWinApp::PraseCommandLine可以帮助你解析,虽然ATL也提供了,但不能解析/Embedding或/Automation,因此楼主必须自己手动解析),看是否包含/Embedding或/Automation命令行参数,包含了说明exe是由COM运行时期库启动的,没有包含说明是普通的启动,就调用父类的Lock();以锁住exe。

再在派生类中重载PostMessageLoop,如上判断(可以通过一个成员变量的记录以避免代码重复)是否应该锁住exe,如果是(即不带有/Embedding或/Automation),调用Unlock();以解锁exe。

如果楼主嫌自己解析命令行参数太麻烦,可以使用MFC提供的帮助类CCommandLineInfo(具体用法请参考MSDN),不过必须为你的ATL工程添加MFC支持。
jeffchen 2003-10-24
  • 打赏
  • 举报
回复
ComServer是使用单一实例类厂吗?如果不是,你看到的可能是新启动的comserver实例。
lop5712 2003-10-24
  • 打赏
  • 举报
回复
“单一实例”指多次要求启动一个应用程序以提供服务时,只启动一个实例,后续的请求都会被处理,但返回的实例句柄是同一个。这个效果一般使用互斥量来实现,如果用ATL编写,可以简单的指定一个宏即可。

楼主的原因是因为没有锁住服务器,当COM客户退出时,它将类厂的引用记数减一,由于为零,因此服务器退出。楼主如果用MFC写的服务器,应该在InitInstance中根据不是以请求启动时(即通过判断命令行参数是否带有/Embber(可能记错),一般向导会自动添加),就调用LockServer(这个名字是乱起的,旨在说明功能,实际实现相同功能的函数随不同的类库不同)以锁定服务器(即增加类厂的引用记数),再在ExitInstance中解锁服务器。对于ATL编写的在具有同样功能的函数中锁定和解锁服务器即可。
longagoer 2003-10-24
  • 打赏
  • 举报
回复
to jeffchen:
什么叫“单一实例”类厂?能给解释一下吗?我的comserver只实现了一个接口。
你的意思是我的第二个测试中,启动comclient后,先前的comserver已经被杀掉了?而我看到的是comclient新创建的comserver?但是com的机制是如果被请求的comserver.exe已经启动的话就不会再启动它了,就直接创建类厂对象了啊。
那如果我想在comclient退出后不结束comserver进程,应该怎么实现呢?多谢

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧