隔离(无注册)COM 组件行为
Posted
技术标签:
【中文标题】隔离(无注册)COM 组件行为【英文标题】:Isolated (Reg Free) COM component behavior 【发布时间】:2010-03-16 16:54:21 【问题描述】:我的处境相当尴尬。
我有一个小型 COM 公开组件(我们称之为 SmallCOM),它是一个 (Delphi) win32 dll,我从托管 C# 程序集中(通过 COM)使用它。
我有一个大的 COM 暴露组件(我们称之为 BigCOM),它是一个 (Delphi) win32 dll,我从同一个托管 c# 程序集中使用它(再次通过 COM)。
而“有趣”的部分是 BigCOM 还通过 COM 实例化和使用 SmallCOM。
所有这些都发生在同一个过程中,出于某种原因,我有时会遇到低级别的无法捕获的异常,告诉我(使用 windgb 分析时):
STACK_COMMAND: .cxr 00000000 ; kb ; ~10s; .ecxr ; kb
SYMBOL_STACK_INDEX: 2
SYMBOL_NAME: SmallCOM+178c6
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: SmallCOM
IMAGE_NAME: SmallCOM.dll
DEBUG_FLR_IMAGE_TIMESTAMP: 2a425e19
FAILURE_BUCKET_ID:
NULL_CLASS_PTR_DEREFERENCE_c0000005_SmallCOM.dll!Unloaded
BUCKET_ID: APPLICATION_FAULT_NULL_CLASS_PTR_DEREFERENCE_INVALID_POINTER_WRITE_SmallCOM+178c6
WATSON_STAGEONE_URL: http://watson.microsoft.com/StageOne/C#Service_exe/2_4_0_1/4ad7147f/ntdll_dll/5_2_3790_3959/45d70ad8/c0000005/0004afb2.htm?Retriage=1
Followup: MachineOwner
我猜 BigCOM 已经完成了 SmallCOM 的工作并释放了它,使其无法从 C# exe 再次使用(并且重新加载它是不可能的,exe 是一个服务,它是高度多线程的,它即使在 BigCOM 工作时也使用这个 SmallCOM)。
所以,我的问题是:在我的 C# exe 中使用独立无注册 COM 来隔离 SmallCOM 会解决问题吗?还是 BigCOM 和 C# exe,仍然共享同一个进程,无论如何都使用同一个 SmallCOM.dll?
提前致谢! 艾蒂安。
【问题讨论】:
听起来像是引用计数问题。 【参考方案1】:如果 dll 已被卸载(这是 COM 运行时会做的事情,它不是由应用程序直接完成的),那么库似乎可能会过早地从 DllCanUnloadNow
返回值(假设是DLL实现的功能)。
如果是这种情况,要么是 SmallCOM 中的一个需要修复的错误,要么是作为创可贴调用 GetModuleHandleEx 并带有 GET_MODULE_HANDLE_EX_FLAG_PIN
标志,这将阻止 DLL 被卸载。
【讨论】:
我怀疑引用计数失败,因为一半对象是由托管代码创建的,而另一半是由非托管代码创建的。我们将尝试显式地实现 DllCanUnloadNow,感谢您的提示!不知道是否使用 Reg Free COM DLL 会被“加载”两次,一次用于托管,一次用于非托管?无论如何,非常感谢!以上是关于隔离(无注册)COM 组件行为的主要内容,如果未能解决你的问题,请参考以下文章