Multithreading 主线程中不存在的MSAA会产生新的行为

Multithreading 主线程中不存在的MSAA会产生新的行为,multithreading,qt,com,atl,Multithreading,Qt,Com,Atl,我对Qt中的Microsoft Active Accessibility和线程有问题。代码示例如下: CComPtr<IAccessible> _pAccMain; HWND _hWnd = ...; // Handle of some window HRESULT hr0 = ::AccessibleObjectFromWindow(_hWnd, OBJID_CLIENT,

我对Qt中的Microsoft Active Accessibility和线程有问题。代码示例如下:

CComPtr<IAccessible> _pAccMain;
HWND _hWnd = ...; // Handle of some window
HRESULT hr0 = ::AccessibleObjectFromWindow(_hWnd,
                                              OBJID_CLIENT,
                                              IID_IAccessible,
                                              (void**)(&_pAccMain));
long childCount = 0;

HRESULT hr1 = _pAccMain->get_accChildCount(&childCount);
CComPtr\u pAccMain;
HWND _HWND=…;//某个窗口的句柄
HRESULT hr0=::AccessibleObject fromWindow(\u hWnd,
OBJID_客户,
IID_i可访问,
(无效**)(&u pAccMain));
长childCount=0;
HRESULT hr1=\u pAccMain->get\u accChildCount(&childCount);
它工作正常,在主线程中,这些函数返回hr0和hr1的成功,我得到了_pAccMain和childCount的正确成功数据。但是,当我创建一个新线程并尝试使用该新线程中的代码时,我在hr0和hr1中再次获得成功,但在_pAccMain和childCount中获得了不同的数据。即,同一代码在不同线程中有多个行为

为什么另一个线程在该示例中有另一个行为

如何修复它

我能修一下吗?

  • 不能保证
    AccessibleObjectFromWindow
    调用返回相同的接口指针,因此
    \u pAccMain
    值不必是指针相等的
  • 此外,来自不同线程(单元)的调用可能涉及封送,在这种情况下,您可能会得到一个代理接口,而不是真正的对象接口;这些是不同的指针,这是设计的行为
  • 通过提到不同的
    childCount
    ,您应该提到工作线程是否为零,或者在子枚举中到底有什么不同
  • COM中的线程之间没有免费的COM指针传递,您的问题表明您正在做什么;只能对MTA线程执行此操作,否则必须封送/取消封送指针才能在另一个线程中获取有效指针

似乎Qt在每个新线程中都悄悄初始化了COM,在使用任何CoInInitializeX之后,它都无法对其执行任何操作。但是,如果您在CoInitializeX之前调用new QThread ConInitialize,一切都会正常,这对我来说是可行的。

只是确认一下,您是否在每个线程中调用
CoInitialize
?如果您在线程之间共享指针,您是否在每个线程中调用
coinitializex(NULL,COINIT\u multi threaded)
?是的,我在尝试使用msaa的线程中成功地调用了coinitializex。我想第二个子句就是我的情况,我得到的是一个代理接口,而不是一个真正的对象接口。但代理只有两个子,我无法从应用程序中获取所需的数据。我可以解决这个问题并在非主线程中获取真实对象接口吗?您可以从同一COM单元获取真实对象。然而,我的猜测是,孩子数量的变化并不是因为COM。MSDN说:我猜这是问题的根源。如果在一个主线程中所有线程都正常,但在其他线程中总是不正常,那么它怎么可能是问题的根源呢?我不明白。。。我在新线程的CoInitializeX中尝试了所有Conit值,但它不影响。我不知道如何才能正确地使用IAccessible,只是不在主线程中。非常感谢你,你让我度过了美好的一天。。。!