C++ 为什么COM不';在新的线程中不工作?
我的问题是在将我的VS2003项目转换为VS2008之后开始的。该解决方案包含3个项目。项目是DLL的。有很多编译错误,然后是一些链接器错误。。。嗯,我打败了他们。现在它根本不起作用;) 因此,支持此DLL之一通过COM与Word进行通信C++ 为什么COM不';在新的线程中不工作?,c++,windows,com,C++,Windows,Com,我的问题是在将我的VS2003项目转换为VS2008之后开始的。该解决方案包含3个项目。项目是DLL的。有很多编译错误,然后是一些链接器错误。。。嗯,我打败了他们。现在它根本不起作用;) 因此,支持此DLL之一通过COM与Word进行通信 Word::_ApplicationPtr d_pApp; Word::_DocumentPtr d_pDoc; void MSWord2003::init() { free(); HRESULT hr; CLSID clsid;
Word::_ApplicationPtr d_pApp;
Word::_DocumentPtr d_pDoc;
void MSWord2003::init()
{
free();
HRESULT hr;
CLSID clsid;
CLSIDFromProgID(L"Word.Application", &clsid);
// Get an interface to the running instance, if any..
IUnknown *pUnk;
hr = GetActiveObject(clsid, NULL, (IUnknown**)&pUnk);
if(hr!=S_OK)
throw MSWord::MSWordException("Nie znaleziono działającej aplikacji MSWord.");
IDispatch* d_pDispApp;
hr = pUnk->QueryInterface(IID_IDispatch, (void**)&d_pDispApp);
if(hr!=S_OK)
throw MSWord::MSWordException("Nie udało się połączyć z aplikacją MSWord.");
pUnk->Release();
pUnk = 0;
d_pApp = d_pDispApp;
d_pDoc = d_pApp->ActiveDocument;
d_pDispApp->AddRef();
d_currIdx = -1;
paragraphsCount = d_pDoc->GetParagraphs()->Count;
footnotesCount = d_pDoc->GetFootnotes()->Count;
endnotesCount = d_pDoc->GetEndnotes()->Count;
}
void MSWord2003::free()
{
if(d_pApp!=0)
{
d_pApp->Release();
d_pApp=0;
}
}
这段代码在VS2003(和其他机器,我的计算机上没有VS2003)上运行,而在VS2008中,它只有在主线程调用它时才能运行。
当被新线程调用时(由CoInitialize初始化),d_pApp未正确初始化-其ptr显示为0
调试时,我在comip.h中找到了代码:
template<typename _InterfacePtr> HRESULT _QueryInterface(_InterfacePtr p) throw()
{
HRESULT hr;
// Can't QI NULL
//
if (p != NULL) {
// Query for this interface
//
Interface* pInterface;
hr = p->QueryInterface(GetIID(), reinterpret_cast<void**>(&pInterface));
// Save the interface without AddRef()ing.
//
Attach(SUCCEEDED(hr)? pInterface: NULL);
}
else {
operator=(static_cast<Interface*>(NULL));
hr = E_NOINTERFACE;
}
return hr;
}
template HRESULT\u QueryInterface(\u InterfacePtr p)throw()
{
HRESULT-hr;
//不能是空的吗
//
如果(p!=NULL){
//查询此接口
//
接口*pInterface;
hr=p->QueryInterface(GetIID(),重新解释强制转换(&pinInterface));
//保存接口而不添加AddRef()。
//
附加(成功(hr)?pInterface:NULL);
}
否则{
运算符=(静态_转换(NULL));
hr=E_NOINTERFACE;
}
返回人力资源;
}
在新线程中,QueryInterface返回E_NOINTERFACE,尽管GetIID()为两个线程返回相同的内容。这就是我被卡住的地方-我不知道,是什么导致了这种行为…在我看来,你不应该用CoInitialize初始化COM,而应该用coinitializex,指定COINIT\u多线程。否则,每个线程都会有单独的单线程COM单元。Word版本在两台机器上都是相同的?您确定主线程的寿命足够长,并且不会调用COM单元吗?根据MSDN:应用程序中调用CoInitialize(0)或CoInitializeX(Conit_APARTMENTTHREADED)的第一个线程必须是调用ConInitialize()的最后一个线程。如果调用顺序不符合此顺序,则。。。应用程序将无法工作。您是在新线程上运行所有这些代码,还是只是其中的一部分?请记住,COM对象只能在最初创建它们的单元中使用。@Soons,好吧,这段代码非常陈旧和混乱,并且没有对COM对象进行初始化的调用。。。尽管它很糟糕,但它并没有导致这个问题。@RaymondChen,新线程调用init()方法。它首先释放了d_pApp。我看不到任何其他“松散”变量。。。GetActiveObject和QueryInterface在init函数中被调用,所以它们也被新线程调用。我试着打电话给CoInitializeEx,这样线程就会在MTA中,但没用。