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

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

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

//implement our own conversion functions

//------------------------//
// Convert char * to BSTR //
//------------------------//
inline BSTR ConvertStringToBSTR(const char* pSrc)
{
    if(!pSrc) return NULL;

    DWORD cwch;

    BSTR wsOut(NULL);

    if(cwch = ::MultiByteToWideChar(CP_ACP, 0, pSrc, 
         -1, NULL, 0))//get size minus NULL terminator
    {
                cwch--;
            wsOut = ::SysAllocStringLen(NULL, cwch);

        if(wsOut)
        {
            if(!::MultiByteToWideChar(CP_ACP, 
                     0, pSrc, -1, wsOut, cwch))
            {
                if(ERROR_INSUFFICIENT_BUFFER == ::GetLastError())
                    return wsOut;
                ::SysFreeString(wsOut);//must clean up
                wsOut = NULL;
            }
        }

    };

    return wsOut;
};

//------------------------//
// Convert BSTR to char * //
//------------------------//
inline char* ConvertBSTRToString(BSTR pSrc)
{
    if(!pSrc) return NULL;

    //convert even embeded NULL
    DWORD cb,cwch = ::SysStringLen(pSrc);

    char *szOut = NULL;

    if(cb = ::WideCharToMultiByte(CP_ACP, 0, 
               pSrc, cwch + 1, NULL, 0, 0, 0))
    {
        szOut = new char[cb];
        if(szOut)
        {
            szOut[cb - 1]  = '\0';

            if(!::WideCharToMultiByte(CP_ACP, 0, 
                pSrc, cwch + 1, szOut, cb, 0, 0))
            {
                delete []szOut;//clean up if failed;
                szOut = NULL;
            }
        }
    }

    return szOut;
};


 原文链接:

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

你可能感兴趣的:(socket,Google,null,delete,buffer,微软)