zoukankan      html  css  js  c++  java
  • 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

    要解决很简单,就是根据错误提示,不用初始化了,把代码中的两个初始化函数删除就可以了

    但是通过上述修改线程类型也可以解决

  • 相关阅读:
    蓝桥杯java 基础练习 完美的代价
    C# 获得手机归属地功能
    c# HttpWebRequest与HttpWebResponse(转)
    C# Winfrom小黄鸡功能调用
    Winfrom 抓取web页面内容代码
    Winform将网页生成图片
    Winform上传下载文件代码
    Jquery LigerUI框架学习(二)之Tree于Tab标签实现iframe功能
    Jquery LigerUI框架学习(一)
    C# 生成简单验证码
  • 原文地址:https://www.cnblogs.com/8335IT/p/14793433.html
Copyright © 2011-2022 走看看