我正在编写一个拥有大量接口和方法的COM服务器。大多数方法的参数和本地参数都是BSTR类型,用作返回值。代码片段如下:
问题在于内存释放部分。这段代码在任何Win XP机器上都运行得非常好,但是在WIN2K8 R2和WIN7上却会崩溃,并指向::SysFreeString()作为罪魁祸首。MSDN无法提供合适的解决方案。
请问有人能帮我找到正确的解决方案吗?
非常感谢:)
更新1: 根据建议,我尝试使用CComBSTR代替原始BSTR,使用直接的CString进行初始化,并排除了SysFreeString()。但是,当它脱离范围时,系统会调用SysFreeString(),从而再次导致崩溃:(
更新2: 使用相同的CComBSTR,我尝试使用SysAllocString()进行分配,问题仍然存在:(
更新3: 我已经尝试过所有的选项,现在只有一个问题:
必须通过SysFreeString()释放使用SysAllocString()/string.AllocSysString()分配的BSTR吗?
更新4: 我忘记提供有关崩溃的信息。当我尝试调试COM服务器时,它会崩溃,并显示错误消息:
"Possible Heap Corruption"
请帮帮我...:(
更新5:
真实代码。根据特定条件从数据库中获取一组数据以填充对象数组。
STDMETHODIMP CApplication::GetAllAddressByName(BSTR bstrParamName, VARIANT *vAdddresses)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
//check the Database server connection
COleSafeArray saAddress;
HRESULT hr;
// Prepare the SQL Strings dan Query the DB
long lRecCount = table.GetRecordCount();
if (lRecCount > 0)
{
//create one dimension safe array for putting details
saAddress.CreateOneDim(VT_DISPATCH,lRecCount);
IAddress *pIAddress = NULL;
//retrieve details
for(long iRet = table.MoveFirst(),iCount=0; !iRet; iRet = table.MoveNext(),iCount++)
{
CComObject<CAddress> *pAddress;
hr = CComObject<CAddress>::CreateInstance(&pAddress);
if (SUCCEEDED(hr))
{
BSTR bstrStreet = ::SysAllocString(table.m_pRecordData->Street);
pAddress->put_StreetName(bstrStreet);
BSTR bstrCity = ::SysAllocString(table.m_pRecordData->City);
pAddress->put_CityName(bstrCity);
}
hr = pAddress->QueryInterface(IID_IAddress, (void**)&pIAddress);
if(SUCCEEDED(hr))
{
saAddress.PutElement(&iCount,pIAddress);
}
}
*vAdddresses=saAddress.Detach();
}
table.Close();
return S_OK;
}
STDMETHODIMP CAddress::put_CityName(BSTR bstrCityName)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
// m_sCityName is of CComBSTR Type
m_sCityName.Empty();//free the old string
m_sCityName = ::SysAllocString(bstrCityName);//create the memory for the new string
return S_OK;
}
问题在于内存释放部分。这段代码在任何Win XP机器上都运行得非常好,但是在WIN2K8 R2和WIN7上却会崩溃,并指向::SysFreeString()作为罪魁祸首。MSDN无法提供合适的解决方案。
请问有人能帮我找到正确的解决方案吗?
非常感谢:)
更新1: 根据建议,我尝试使用CComBSTR代替原始BSTR,使用直接的CString进行初始化,并排除了SysFreeString()。但是,当它脱离范围时,系统会调用SysFreeString(),从而再次导致崩溃:(
更新2: 使用相同的CComBSTR,我尝试使用SysAllocString()进行分配,问题仍然存在:(
更新3: 我已经尝试过所有的选项,现在只有一个问题:
必须通过SysFreeString()释放使用SysAllocString()/string.AllocSysString()分配的BSTR吗?
更新4: 我忘记提供有关崩溃的信息。当我尝试调试COM服务器时,它会崩溃,并显示错误消息:
"Possible Heap Corruption"
请帮帮我...:(
obj.Name = ::SysAllocString(someString);
吗?此外,考虑使用CComBSTR
或_bstr_t
代替原始的 BSTR,这将为您节省很多麻烦。 - Bhargav