COM DLL依赖项中的多个进程和静态DLL数据的副本

时间:2013-03-12 11:53:37

标签: c# c++ windows com process

我希望了解COM DLL运行中的一些意外行为,其中出现静态C ++数据正在多个进程之间共享。环境有点复杂,我对各种COM线程模型的理解相当薄弱,我希望有人可以帮忙。

环境

  • 运行多个C#Web服务的64位操作系统上的IIS服务器,每个服务都在自己的32位应用程序池中,因此处理
    • 池具有“启用32位应用程序”=真实设置
  • 每个32位C#服务调用一个不同的进程内32位COM DLL(因此服务A调用COM DLL 1,服务C调用COM DLL 2. COM DLL使用Qt 4.8 ActiveQt用C ++编写
  • COM DLL依赖于多个32位C ++ DLL,这些DLL是共享的,即COM DLL 1和2都依赖于Utilities.dll
  • 据我所知,没有为COM DLL设置ThreadingModel,所以我期待系统将回退到主STA上。
    • 我知道这是不赞成的,但我目前没有足够的知识来改变它。
  • Utilities.dll包含一些静态C ++数据
  • COM DLL是使用“regsvr32”注册的,并且似乎没有列在“组件服务”中,尽管我对后者的了解很少。

观察到的问题是,Utilities.dll中的静态数据似乎最终会在不同的IIS进程之间共享,从而产生不良后果。我曾预料到,由于COM在主STA中,它们将被访问,好像它不是线程安全的,每个进程都会获得自己的DLL静态数据副本,但似乎并非如此。

有人可以解释静态数据最终如何在进程之间共享?

我该如何避免这种情况? (除了重构代码以删除当前不可行的所有静态数据)

1 个答案:

答案 0 :(得分:1)

如果您看到COM对象之间共享数据,则意味着它们托管在同一进程中。是的,可以在进程之间共享数据,但不是偶然的。由于您的应用程序池是不同的进程,因此必须将这些COM对象托管在进程外,并且它只是加载到应用程序池中的存根。

如果您可以控制Utilities.dll(听起来就像这样),我会尝试添加一些调试信息,以找出托管COM对象的进程ID。我希望您会发现它与应用程序池ID不匹配,并且您将能够使用该ID来查明正在发生的事情。

理想情况下,精心设计的COM对象存在于哪里应该无关紧要,这应该是一个实现细节。是否有可能取消共享数据结构?