我写它有很多接口和方法的COM服务器。而且大多数方法都以BSTR作为参数,并将其用作返回的本地参数。一个片段看起来像使用:: SysFreeString()释放BSTR。更多的平台依赖?
更新5:
真正的代码。这从基于特定条件的数据库中获取数据库来填充Object数组。
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;
}
问题出在Memory Freeing部分。该代码在任何Win XP的机器很细,但是当涉及到WIN2K8 R2和Win7的代码崩溃,指向:: SysFreeString()的罪魁祸首。 MSDN不适合该解决方案。
任何人都可以请找到合适的解决方案帮助吗?
感谢很多提前:)
更新1:
我已经使用的CComBSTR按照建议在原BSTR的地方尝试过,用直接的CString的初始化和排除SysFreeString( )。但我的麻烦,在获取超出范围的系统调用SysFreeString()这又导致崩溃:(
更新2: 在相同的CComBSTR我尝试使用SysAllocString(分配),该问题仍然是相同的:(
更新3: 我厌倦了所有的选项,并在和平,我铭记唯一的问题
是否有必要通过自由的SysFreeString BSTR(),它是使用SysAllocString()/ string.AllocSysString()分配?
更新4: 我错过了提供有关崩溃的信息。当我试图调试COM服务器崩溃了错误说
“可能堆损坏”
。请帮我离开这里.. :(
IMO,分配器应该是更自由。也就是说,调用FooMethod的客户端应该执行bstrName的分配。它也应该释放它。另外,你的代码很混乱,你有bstrname和bstrName。也许obj.Name = bstrName;应该真的是obj.Name = bstrname; ? – 2012-02-27 14:54:37
不应该代码类似于'obj.Name = :: SysAllocString(someString);'。另外,考虑使用'CComBSTR'或'_bstr_t'代替原始的BSTR,会为您节省很多麻烦。 – 2012-02-27 15:14:55
是的,有必要释放分配的内存块。请为我们提供使用'obj'变量的完整代码。否则,这是不可能的,以帮助您找到问题 – 2012-02-29 19:51:24