c# - COM DLL 依赖项中静态 DLL 数据的多个进程和拷贝

标签 c# c++ windows com process

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

环境

  • 64 位操作系统上的 IIS 服务器运行多个 C# 网络服务,每个服务都在其自己的 32 位应用程序池中,因此进程
    • 池具有“启用 32 位应用程序”=True 设置
  • 每个 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,即 COM DLL 1 和 2 都依赖于 Utilities.dll
  • 据我所知,没有为 COM DLL 设置 ThreadingModel,因此我预计系统将回退到主 STA。
    • 我知道这是不受欢迎的,但我目前没有足够的知识来改变它。
  • Utilities.dll 包含一些静态 C++ 数据
  • COM DLL 是使用“regsvr32”注册的,似乎没有列在“组件服务”中,尽管我对后者知之甚少。

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

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

我怎样才能避免这种情况? (除了重构代码以删除所有静态数据,目前这并不可行)

最佳答案

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

如果您可以控制 Utilities.dll(听起来您确实可以),我会尝试添加一些调试信息以找出托管 COM 对象的进程 ID。我希望您会发现它与应用程序池 ID 不匹配,并且您将能够使用该 ID 来了解发生了什么。

理想情况下,设计良好的 COM 对象位于何处无关紧要,这应该是某种实现细节。是否可以取消共享数据结构?

关于c# - COM DLL 依赖项中静态 DLL 数据的多个进程和拷贝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15360461/

相关文章:

c# - C# .NET 4.0 中的数据绑定(bind)设置时间缓慢

c# - 如何使用 Pinvoke 返回字符串数组

c++ - 带有字符串数组的段错误c++

c++ - 从 SECURITY_DESCRIPTOR 转换为字符串并再次转换回来不起作用

windows - 内置管理员帐户无权执行 Windows 10 中的某些操作

c - 在 Windows 上处理 fpu 异常

c# - 如何使用 Magick.NET 将动画 webp 图像转换为动画 gif?

c# - 如何在自托管 Web API 上发送文件并在服务器上处理它?

c++ - 带有关键字 this 的构造函数中的段错误

c++ - 我可以在函数头中包含 cppcheck 抑制吗?