QT中使用CoInitializeEx
1 在使用winmm.lib 里边的MMDevice的时候,用于音频采集播放等操作,在使用控制台程序直接操作的时候是没问题的;但是转到QTCreator的时候,封装COM的Dll运行的时候CoinitializeEX 会报错,80010106.
这里边找到一篇博客:
CoInitializeEx 在GUI程序中,不再是这样: hres = CoInitializeEx(0, COINIT_MULTITHREADED); hres = CoInitializeEx(0, COINIT_APARTMENTTHREADED);
CoInitialize与CoInitializeEx的区别:
CoInitialize指明以单线程方式创建。
CoInitializeEx可以指定COINIT_MULTITHREADED以多线程方式创建。
创建单线程方式的COM服务器时不用考虑串行化问题,多线程COM服务器就要考虑。
在使用中,使用CoInitialize创建可使对象直接与线程连接,得到最高的性能。创建多线程对象可以直接接收所有线程的调用,不必像单线程那样需要消息排队,但却需要COM创建线程间汇集代理,这样访问效率不高。
CoInitializeSecurity返回RPC_E_TOO_LATE也是正确
你会发现CoInitializeSecurity返回的不是想要的,是一个特别大的负数,但是转换为十六进制为0x80010119
这时候发现0x80010119就是RPC_E_TOO_LATE
因此我们需要修改代码:
if (FAILED(hres))
{
qDebug() << "Failed to initialize security. "
<< "Error code = 0x"
<< hex << hres << endl;
CoUninitialize();
return "";
}
修改为:
if ((hres != RPC_E_TOO_LATE) && FAILED(hres))
{
qDebug() << "Failed to initialize security. "
<< "Error code = 0x"
<< hex << hres << endl;
CoUninitialize();
return "";
}
调用函数ExecQuery时,编译报错
错误为:
error: undefined reference to `_com_util::ConvertStringToBSTR(char const*)@4
因此我们需要正确的方式从QString转到BSTR,因此修改代码:
由:
hres = pSvc->ExecQuery(
bstr_t("WQL"),
bstr_t("SELECT * FROM Win32_VideoController"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator);
改为:
BSTR sql = SysAllocString(L"SELECT * FROM Win32_VideoControlle");
BSTR wql = SysAllocString(L"WQL");
hres = pSvc->ExecQuery(wql,
sql,
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator);
这里用到了SysAllocString
SysAllocString函数说明:
This function allocates a new string and copies the passed string into it.
Next函数的返回值正确,但是uReturn等于0
到最后,我们使用了Next进行查询,但是发现该函数的返回值hres是正确的,uReturn始终为0
hres = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
完全是自己马虎造成,不知道细心的您发现了没有上面的代码:
BSTR sql = SysAllocString(L"SELECT * FROM Win32_VideoControlle");
再看一下,是不是SQL语句的拼写错误。
果然,Win32_VideoControlle错误了,应该是Win32_VideoController
修正为:
BSTR sql = SysAllocString(L"SELECT * FROM Win32_VideoController");
————————————————
转载---本文为CSDN博主「江南-一苇渡江」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文
原因:
COM代码被放到了DLL中被调用--转载自博客园:
因为加载DLL的时候会自动初始化COM库。所以再初始化就会报错,返回错误码:0x80010106 ----- Cannot change thread mode after it is set
要解决很简单,就是根据错误提示,不用初始化了,把代码中的两个初始化函数删除就可以了
但是通过上述修改线程类型也可以解决
浙公网安备 33010602011771号