通过WMI读取Win32_Processor属性时访问bstrVal触发Access Violation异常
问题分析与解决
核心原因
你遇到的Access Violation根本原因是属性类型不匹配:
- Win32_Processor的
Name属性是字符串类型(VARIANT的vt字段值为VT_BSTR),直接访问bstrVal安全有效; - 但
NumberOfCores是32位整数类型(vt值为VT_I4),此时vtProp.bstrVal指向的内存并非合法BSTR指针,强行访问必然触发内存违规。
解决方案
必须先检查VARIANT的vt字段,根据属性类型选择对应字段访问:
- 字符串类型(VT_BSTR):使用
bstrVal - 整数类型(VT_I4):使用
lVal - 其他类型同理,比如无符号整数(VT_UI4)对应
ulVal
另外注意:SysAllocString分配的BSTR需要手动释放,避免内存泄漏。
修正后的代码
HRESULT hres; IWbemClassObject* pclsObj = NULL; ULONG uReturn = 0; IEnumWbemClassObject* pEnumerator = NULL; // pSvc is a IWbemServices object. hres = pSvc->ExecQuery( bstr_t("WQL"), bstr_t("SELECT * FROM Win32_Processor"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); while (pEnumerator) { hres = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); if (0 == uReturn) { break; } VARIANT vtProp; VariantInit(&vtProp); // 访问Name属性(字符串类型) BSTR propName = SysAllocString(L"Name"); hr = pclsObj->Get(propName, 0, &vtProp, 0, 0); SysFreeString(propName); // 释放分配的BSTR if(SUCCEEDED(hr)) { if(vtProp.vt == VT_BSTR && vtProp.bstrVal != nullptr) { wcout << " Name : " << vtProp.bstrVal << endl; } VariantClear(&vtProp); } // 访问NumberOfCores属性(整数类型) VariantInit(&vtProp); BSTR corePropName = SysAllocString(L"NumberOfCores"); hr = pclsObj->Get(corePropName, 0, &vtProp, 0, 0); SysFreeString(corePropName); if(SUCCEEDED(hr)) { if(vtProp.vt == VT_I4) { wcout << " Number Of Cores : " << vtProp.lVal << endl; } VariantClear(&vtProp); } pclsObj->Release(); }
额外注意事项
- 每次调用
Get前需重新初始化VARIANT,或在VariantClear后再次初始化 - 所有通过
SysAllocString分配的BSTR必须用SysFreeString释放,防止内存泄漏 - 即使
Get返回成功,也要检查VARIANT的类型和字段有效性(比如BSTR是否为nullptr)
内容的提问来源于stack exchange,提问作者kasra
相关产品推荐
相关产品推荐

