隔离(无注册)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 组件行为的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Vue.js 中隔离组件

如何隔离 Vuetify 全局样式

浅析Spring事务传播行为和隔离级别

事务的隔离级别和传播行为

理解 spring 事务传播行为与数据隔离级别

Reg Free COM - 隔离 COM 参考 - 缺失值“(默认)”