COM中的一个方法,用VC调用正确,C#调用出错,搞不懂?
在暴露的方法中,直接调用一个类的方法,该方法主要是获取主板编号信息,内容如下:
INT CWMI::WMI_DeviceQuery( INT iQueryType, T_DEVICE_PROPERTY *properties, INT iSize )
{
HRESULT hres;
INTiTotal = 0;
// 判断查询类型是否支持
if( (iQueryType < 0) || (iQueryType >= sizeof(szWQLQuery)/sizeof(T_WQL_QUERY)) )
{
return -1;// 查询类型不支持
}
// 初始化COM
hres = CoInitialize( NULL);
if( FAILED(hres) )
{
return -2;
}
// 设置COM的安全认证级别
hres = CoInitializeSecurity(
NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE,
NULL
);
if( FAILED(hres) )
{
CoUninitialize();
return -2;
}
// 获得WMI连接COM接口
IWbemLocator *pLoc = NULL;
hres = CoCreateInstance(
CLSID_WbemLocator,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
reinterpret_cast<LPVOID*>(&pLoc)
);
if( FAILED(hres) )
{
CoUninitialize();
return -2;
}
// 通过连接接口连接WMI的内核对象名"ROOT\\CIMV2"
IWbemServices *pSvc = NULL;
hres = pLoc->ConnectServer(
_bstr_t( L"ROOT\\CIMV2" ),
NULL,
NULL,
NULL,
0,
NULL,
NULL,
&pSvc
);
if( FAILED(hres) )
{
pLoc->Release();
CoUninitialize();
return -2;
}
// 设置请求代理的安全级别
hres = CoSetProxyBlanket(
pSvc,
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE,
NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE
);
if( FAILED(hres) )
{
pSvc->Release();
pLoc->Release();
CoUninitialize();
return -2;
}
// 通过请求代理来向WMI发送请求
IEnumWbemClassObject *pEnumerator = NULL;
hres = pSvc->ExecQuery(
bstr_t("WQL"),
bstr_t( szWQLQuery[iQueryType].szSelect ),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator
);
if( FAILED(hres) )
{
pSvc->Release();
pLoc->Release();
CoUninitialize();
return -3;
}
// 循环枚举所有的结果对象
while( pEnumerator )
{
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
if( (properties != NULL) && (iTotal >= iSize) )
{
break;
}
pEnumerator->Next(
WBEM_INFINITE,
1,
&pclsObj,
&uReturn
);
if( uReturn == 0 )
{
break;
}
if( properties != NULL )
{// 获取属性值
VARIANT vtProperty;
VariantInit( &vtProperty );
pclsObj->Get( szWQLQuery[iQueryType].szProperty, 0, &vtProperty, NULL, NULL );
StringCchCopy( properties[iTotal].szProperty, PROPERTY_MAX_LEN, W2T(vtProperty.bstrVal) );
VariantClear( &vtProperty );
// 对属性值做进一步的处理
if( WMI_DoWithProperty( iQueryType, properties[iTotal].szProperty, PROPERTY_MAX_LEN ) )
{
iTotal++;
}
}
else
{
iTotal++;
}
pclsObj->Release();
} // End While
// 释放资源
pEnumerator->Release();
pSvc->Release();
pLoc->Release();
CoUninitialize();
return iTotal;
}
[解决办法]
*pVal = _bstr_t(temp);
这种返回方法是有问题的。因为函数体返回后,_bstr_t已经被析构了,返回的字符串指针为野指针。建议:
_bstr_t bv(temp);
*pVal=bv.Detach();
