_com_util::ConvertBSTRToString BUG解决方案(转载)

时间:2020-12-30 15:56:12

最近做了一个COM组件负责socket通讯,发现一个无法解决的问题,当socket发送较慢(当连一个代理服务器发送时通常会慢一些),COM组件提供的接口函数中将BSTR转换为char*时会造成程序崩溃,具体异常是操作了受保护的内存之类,跟踪代码发现出问题的代码为:_com_util::ConvertBSTRToString,这是微软提供标准转换代码,心灰意冷,以为这个问题绕不过去了。

 后来无意间google到下面这篇文章,原来别人也发现了微软该函数的bug,就是函数内内存申请的问题,作者修复完的函数如下: 

[cpp] view plaincopy
  1. //implement our own conversion functions  
  2.   
  3. //------------------------//  
  4. // Convert char * to BSTR //  
  5. //------------------------//  
  6. inline BSTR ConvertStringToBSTR(const char* pSrc)  
  7. {  
  8.     if(!pSrc) return NULL;  
  9.   
  10.     DWORD cwch;  
  11.   
  12.     BSTR wsOut(NULL);  
  13.   
  14.     if(cwch = ::MultiByteToWideChar(CP_ACP, 0, pSrc,   
  15.          -1, NULL, 0))//get size minus NULL terminator  
  16.     {  
  17.                 cwch--;  
  18.             wsOut = ::SysAllocStringLen(NULL, cwch);  
  19.   
  20.         if(wsOut)  
  21.         {  
  22.             if(!::MultiByteToWideChar(CP_ACP,   
  23.                      0, pSrc, -1, wsOut, cwch))  
  24.             {  
  25.                 if(ERROR_INSUFFICIENT_BUFFER == ::GetLastError())  
  26.                     return wsOut;  
  27.                 ::SysFreeString(wsOut);//must clean up  
  28.                 wsOut = NULL;  
  29.             }  
  30.         }  
  31.   
  32.     };  
  33.   
  34.     return wsOut;  
  35. };  
  36.   
  37. //------------------------//  
  38. // Convert BSTR to char * //  
  39. //------------------------//  
  40. inline char* ConvertBSTRToString(BSTR pSrc)  
  41. {  
  42.     if(!pSrc) return NULL;  
  43.   
  44.     //convert even embeded NULL  
  45.     DWORD cb,cwch = ::SysStringLen(pSrc);  
  46.   
  47.     char *szOut = NULL;  
  48.   
  49.     if(cb = ::WideCharToMultiByte(CP_ACP, 0,   
  50.                pSrc, cwch + 1, NULL, 0, 0, 0))  
  51.     {  
  52.         szOut = new char[cb];  
  53.         if(szOut)  
  54.         {  
  55.             szOut[cb - 1]  = '\0';  
  56.   
  57.             if(!::WideCharToMultiByte(CP_ACP, 0,   
  58.                 pSrc, cwch + 1, szOut, cb, 0, 0))  
  59.             {  
  60.                 delete []szOut;//clean up if failed;  
  61.                 szOut = NULL;  
  62.             }  
  63.         }  
  64.     }  
  65.   
  66.     return szOut;  
  67. };  


 原文链接:

http://www.codeproject.com/Articles/1969/BUG-in-_com_util-ConvertStringToBSTR-and-_com_util