我正在编写一个具有大量接口和方法的 COM 服务器。并且大多数方法都将 BSTR 作为参数并作为用于返回的本地参数。一个片段看起来像
更新 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: 我厌倦了所有的选择,我心里只想着一个问题
是否有必要通过使用 SysAllocString()/string.AllocSysString() 分配的 SysFreeString() 来释放 BSTR?
更新 4: 我错过了提供有关崩溃的信息。当我尝试调试 COM 服务器时出现错误提示
“可能的堆损坏”
. 请帮我离开这里.. :(