gpt4 book ai didi

multithreading - 旧版 VB6 COM+ DLL 调用 native Win32 DLL——STA 的线程问题?

转载 作者:行者123 更新时间:2023-12-04 12:56:32 26 4
gpt4 key购买 nike

遇到第一眼看起来像 MT 问题的东西,但我试图详细了解 COM+ 使用的 STA 模型。

实际上,我有一个用 VB6 编写的遗留 COM+ 组件,它调用用 C++ 编写的 native (即非 COM)Win32 DLL。

有一些间歇性(并且无法在测试中重现)问题,我添加了一些调试代码来找出发生了什么并发现当问题发生时,我在文件中交错了日志消息 - 所以它暗示了 DLL被两个线程同时调用。

现在日志记录到基于 _getpid() 和 GetCurrentThreadId() 的每个线程文件中,所以当调用 C++ DLL 中的代码时,它似乎在同一线程上同时被调用两次。我对 STA 的理解表明,这可能是这种情况,因为 COM 将对象的各个实例编码到单个线程上,然后随意挂起和恢复执行。

不幸的是,我不知道从这里去哪里。我读到我应该在 DllMain() 中调用 CoInitialiseEx() 来告诉 COM 这是一个 STA DLL,但其他地方说这仅对 COM DLL 有效,对 native DLL 没有任何影响。唯一的其他选择是将 DLL 的一部分包装为关键部分以序列化访问(采取任何影响下巴的性能)。

我可以尝试重新设计 DLL,但没有共享状态或全局变量 - 一切都在局部变量中,所以理论上每个调用都应该有自己的堆栈,但我想知道 STA 模型是否基本上对此有一些奇怪的影响并在与另一个调用相同的入口点重新进入已加载的 DLL。不幸的是,我不知道如何证明或检验这个理论。

问题基本上是:

  • 当 STA COM+ 组件调用 native DLL 时,STA 模型中没有任何内容可
    防止事件的“线程”被挂起并将控制权传递给 DLL 调用中间的另一个“线程”?
  • CoInitialiseEx() 是否是解决此问题的正确方法?
  • 如果 (1) 或 (2) 都不是“好的”假设,那么发生了什么?
  • 最佳答案

    在单元线程 COM 服务器中,COM 类的每个实例都保证由单个线程访问。这意味着 实例 是线程安全的。但是,可以使用不同的线程同时创建许多实例。现在,就 COM 服务器而言,您的 native DLL 不必做任何特殊的事情。想想每个可执行文件都使用的 kernel32.dll - 当被 COM 服务器使用时,它是否会初始化 COM?

    从 DLL 的角度来看,您必须确保您是线程安全的,因为不同的实例可以同时调用您。在这种情况下,STA 不会保护您。既然您说您没有使用任何全局变量,我只能假设问题出在其他地方,并且恰好在似乎指向 COM 内容的情况下显示。你确定你没有一些普通的旧 C++ 内存问题吗?

    关于multithreading - 旧版 VB6 COM+ DLL 调用 native Win32 DLL——STA 的线程问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1057524/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com