代码之家  ›  专栏  ›  技术社区  ›  Callie J

旧的VB6 COM+DLL调用到本机Win32 DLL——STA的线程问题?

  •  7
  • Callie J  · 技术社区  · 17 年前

    现在,日志记录将转到基于_getpid()和GetCurrentThreadId()的每个线程文件,因此当调用C++DLL中的代码时,它似乎会在同一时间在同一线程上被调用两次。我对STA的理解表明,当COM将对象的各个实例编组到单个线程上时,可能会出现这种情况。

    1. CoInitialiseEx()是解决这个问题的正确方法吗?
    2. 如果(1)或(2)都不是“好”的假设,那会发生什么?
    2 回复  |  直到 17 年前
        1
  •  1
  •   Eran    17 年前

    实例

        2
  •  0
  •   Mike Dimmick    16 年前

    我怀疑你的问题是,在被调用的DLL的某个深处,它对另一个单元(同一进程中的另一个线程,或MTA中的一个对象,或完全是另一个进程)进行了出站COM调用。COM允许等待出站调用结果的STA线程接收另一个入站调用,并对其进行递归处理。它仅用于同一对象之间的持续对话,即A调用B,B回调A,A再次回调B,但如果你向多个客户端分发了接口指针,或者客户端将接口指针共享给另一个客户端,它可以接收来自其他对象的调用。通常,将指向单个线程对象的接口指针分发给多个客户端线程是一个坏主意,因为它们只需要互相等待。每个线程创建一个worker对象。

    COM不能在任何线程上随意挂起和恢复执行——STA线程上的新传入调用只能通过消息泵到达。当“阻塞”等待响应时,STA线程实际上是在泵送消息,与消息过滤器(请参阅IMessageFilter)检查是否应该处理该消息。但是,消息处理程序不得进行新的传出调用——如果这样做,COM将返回RPC_ENCTALOUT_INEXTERNALCALL错误(“在消息过滤器内调用是非法的。”)

    如果在本机DLL中的任何位置都有消息泵(GetMessage/DispatchMessage),也可能会出现类似的问题。我在VB的DoEvents接口过程中遇到了问题。

    推荐文章