Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. How to convert LPTSTR to BSTR?

How to convert LPTSTR to BSTR?

Scheduled Pinned Locked Moved C / C++ / MFC
questionjsonperformancetutorialannouncement
14 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B balakrishnan vinchu

    In my project i am using FormatMessage API which is returning the LPTSTR buffer pointer lpMsgBuf, if i use CComBstr Message(lpMsgBuf); to copy the lpMsgBuf to BSTR. But this conversion shows memory leak. I am using LocalFree(lpMsgBuf); to release the lpMsgBuf. I am using USES_CONVERSION macro also. Is there anyway to resolve this? or what is the correct way to convert LPTSTR to BSTR? Thanks in advance.

    Regards, Bala

    C Offline
    C Offline
    CPallini
    wrote on last edited by
    #4

    Probably posting your code will help. :)

    If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
    This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke

    B 1 Reply Last reply
    0
    • C CPallini

      Probably posting your code will help. :)

      If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
      This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke

      B Offline
      B Offline
      balakrishnan vinchu
      wrote on last edited by
      #5

      Here is my code: //Functions used to report the Error STDMETHODIMP CVBErrAgent::ReportError(IErrMsg *pErrMsg, SAFEARRAY** args) { //CCOmBstr variables for unformatted and formatted message CComBSTR formatstring, message; pErrMsg->get_ErrMsg(&formatstring); //Function to format the message. This function uses FormatMessage API to get formatted string. FormatMessageFromString(formatstring, args, &message); pErrMsg->put_ErrMsg(message); tlErrorBehavior behav; pErrMsg->get_Behavior(&behav); if(behav != tlErrorIgnore) return CErrSvcClientImpl::tl_Error(pErrMsg); return S_FALSE; } HRESULT CVBErrAgent::FormatMessageFromString(BSTR formatstring, SAFEARRAY **args, BSTR *outputstring) { std::vector vecargs; VARIANT HUGEP * pvar; long lbound, ubound, elcount; //Codes to read SAFEARRAY and creates the argsarray vector, this will be passed to FormatMessage API. if (FAILED (SafeArrayGetLBound(*args, 1, &lbound)) || FAILED (SafeArrayGetUBound(*args, 1, &ubound))) return E_INVALIDARG; elcount = ubound - lbound + 1; if(elcount == 1) { SafeArrayAccessData(*args, (void HUGEP **)&pvar); //If the SAFEARRAY consists of a single VARIANT that is of type VT_ARRAY then //We want to call SafeArrayToVector using the embedded array. if(pvar[0].vt & VT_ARRAY) { SafeArrayToVector(pvar->parray, vecargs); } else SafeArrayToVector(*args, vecargs); SafeArrayUnaccessData(*args); } else SafeArrayToVector(*args, vecargs); std::vector::iterator it; int count = vecargs.size(); vector argsarray(count); USES_CONVERSION; for(it = vecargs.begin(), count = 0; it != vecargs.end(); it++, count++) { if((*it).vt & VT_BSTR) { if((*it).vt & VT_BYREF) argsarray[count] = reinterpret_cast(OLE2T(*(*it).pbstrVal)); else argsarray[count] = reinterpret_cast(OLE2T((*it).bstrVal)); } else if((*it).vt & VT_I4 || (*it).vt & VT_I2) { if((*it).vt & VT_BYREF) argsarray[count] = reinterpret_cast(*(*it).plVal); else argsarray[count] = reinterpret_cast((*it).lVal); } } LPTSTR lpMsgBuf; DWORD messageflags = FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY ; DWORD retval; //Format the message from the format string. retval = FormatMessage( messageflags, OLE2T(formatstring), NULL, LANG_SYSTEM_DEFAULT, (LPTSTR) &lpMsgBuf, 0, (va_list*)&argsarray[0] ); i

      C R 2 Replies Last reply
      0
      • B balakrishnan vinchu

        Here is my code: //Functions used to report the Error STDMETHODIMP CVBErrAgent::ReportError(IErrMsg *pErrMsg, SAFEARRAY** args) { //CCOmBstr variables for unformatted and formatted message CComBSTR formatstring, message; pErrMsg->get_ErrMsg(&formatstring); //Function to format the message. This function uses FormatMessage API to get formatted string. FormatMessageFromString(formatstring, args, &message); pErrMsg->put_ErrMsg(message); tlErrorBehavior behav; pErrMsg->get_Behavior(&behav); if(behav != tlErrorIgnore) return CErrSvcClientImpl::tl_Error(pErrMsg); return S_FALSE; } HRESULT CVBErrAgent::FormatMessageFromString(BSTR formatstring, SAFEARRAY **args, BSTR *outputstring) { std::vector vecargs; VARIANT HUGEP * pvar; long lbound, ubound, elcount; //Codes to read SAFEARRAY and creates the argsarray vector, this will be passed to FormatMessage API. if (FAILED (SafeArrayGetLBound(*args, 1, &lbound)) || FAILED (SafeArrayGetUBound(*args, 1, &ubound))) return E_INVALIDARG; elcount = ubound - lbound + 1; if(elcount == 1) { SafeArrayAccessData(*args, (void HUGEP **)&pvar); //If the SAFEARRAY consists of a single VARIANT that is of type VT_ARRAY then //We want to call SafeArrayToVector using the embedded array. if(pvar[0].vt & VT_ARRAY) { SafeArrayToVector(pvar->parray, vecargs); } else SafeArrayToVector(*args, vecargs); SafeArrayUnaccessData(*args); } else SafeArrayToVector(*args, vecargs); std::vector::iterator it; int count = vecargs.size(); vector argsarray(count); USES_CONVERSION; for(it = vecargs.begin(), count = 0; it != vecargs.end(); it++, count++) { if((*it).vt & VT_BSTR) { if((*it).vt & VT_BYREF) argsarray[count] = reinterpret_cast(OLE2T(*(*it).pbstrVal)); else argsarray[count] = reinterpret_cast(OLE2T((*it).bstrVal)); } else if((*it).vt & VT_I4 || (*it).vt & VT_I2) { if((*it).vt & VT_BYREF) argsarray[count] = reinterpret_cast(*(*it).plVal); else argsarray[count] = reinterpret_cast((*it).lVal); } } LPTSTR lpMsgBuf; DWORD messageflags = FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY ; DWORD retval; //Format the message from the format string. retval = FormatMessage( messageflags, OLE2T(formatstring), NULL, LANG_SYSTEM_DEFAULT, (LPTSTR) &lpMsgBuf, 0, (va_list*)&argsarray[0] ); i

        C Offline
        C Offline
        CPallini
        wrote on last edited by
        #6

        In your FormatMessage call

        balakrishnan vinchu wrote:

        retval = FormatMessage( messageflags, OLE2T(formatstring), NULL, LANG_SYSTEM_DEFAULT, (LPTSTR) &lpMsgBuf, 0, (va_list*)&argsarray[0] );

        The line

        (LPTSTR) &lpMsgBuf,

        is wrong. It should be simply

        lpMsgBuf,
        Forget it. :)

        If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
        This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke

        modified on Wednesday, May 7, 2008 5:40 AM

        B 1 Reply Last reply
        0
        • C CPallini

          In your FormatMessage call

          balakrishnan vinchu wrote:

          retval = FormatMessage( messageflags, OLE2T(formatstring), NULL, LANG_SYSTEM_DEFAULT, (LPTSTR) &lpMsgBuf, 0, (va_list*)&argsarray[0] );

          The line

          (LPTSTR) &lpMsgBuf,

          is wrong. It should be simply

          lpMsgBuf,
          Forget it. :)

          If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
          This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke

          modified on Wednesday, May 7, 2008 5:40 AM

          B Offline
          B Offline
          balakrishnan vinchu
          wrote on last edited by
          #7

          I changed my code as you explained in previous mail. LPTSTR lpMsgBuf = NULL; DWORD messageflags = FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY ; DWORD retval; //Format the message from the format string. retval = FormatMessage( messageflags, OLE2T(formatstring), NULL, LANG_SYSTEM_DEFAULT, lpMsgBuf, // Suggested to pass simply lpMsgBug 0, (va_list*)&argsarray[0] ); if (!retval) return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); CComBSTR message(lpMsgBuf); *outputstring = message.Detach(); LocalFree(lpMsgBuf); Now i am not getting the Formatted message, since retval returned from FormatMessgae API is zero (i.e 0), Because of this CComBSTR message didn't created. Also if i wont initialize lpMsgBuf = NULL, then functions just gives exception. Give me some suggestion. Thanks

          Regards, Bala

          M B C 3 Replies Last reply
          0
          • B balakrishnan vinchu

            I changed my code as you explained in previous mail. LPTSTR lpMsgBuf = NULL; DWORD messageflags = FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY ; DWORD retval; //Format the message from the format string. retval = FormatMessage( messageflags, OLE2T(formatstring), NULL, LANG_SYSTEM_DEFAULT, lpMsgBuf, // Suggested to pass simply lpMsgBug 0, (va_list*)&argsarray[0] ); if (!retval) return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); CComBSTR message(lpMsgBuf); *outputstring = message.Detach(); LocalFree(lpMsgBuf); Now i am not getting the Formatted message, since retval returned from FormatMessgae API is zero (i.e 0), Because of this CComBSTR message didn't created. Also if i wont initialize lpMsgBuf = NULL, then functions just gives exception. Give me some suggestion. Thanks

            Regards, Bala

            M Offline
            M Offline
            Mukesh Kumar
            wrote on last edited by
            #8

            Once try this initialize lpMsgBuf as: LPVOID lpMsgBuf; and inside FormatMessage write lpMsgBuf as: (LPTSTR) &lpMsgBuf,

            Mukesh Kumar Software Engineer

            1 Reply Last reply
            0
            • B balakrishnan vinchu

              Here is my code: //Functions used to report the Error STDMETHODIMP CVBErrAgent::ReportError(IErrMsg *pErrMsg, SAFEARRAY** args) { //CCOmBstr variables for unformatted and formatted message CComBSTR formatstring, message; pErrMsg->get_ErrMsg(&formatstring); //Function to format the message. This function uses FormatMessage API to get formatted string. FormatMessageFromString(formatstring, args, &message); pErrMsg->put_ErrMsg(message); tlErrorBehavior behav; pErrMsg->get_Behavior(&behav); if(behav != tlErrorIgnore) return CErrSvcClientImpl::tl_Error(pErrMsg); return S_FALSE; } HRESULT CVBErrAgent::FormatMessageFromString(BSTR formatstring, SAFEARRAY **args, BSTR *outputstring) { std::vector vecargs; VARIANT HUGEP * pvar; long lbound, ubound, elcount; //Codes to read SAFEARRAY and creates the argsarray vector, this will be passed to FormatMessage API. if (FAILED (SafeArrayGetLBound(*args, 1, &lbound)) || FAILED (SafeArrayGetUBound(*args, 1, &ubound))) return E_INVALIDARG; elcount = ubound - lbound + 1; if(elcount == 1) { SafeArrayAccessData(*args, (void HUGEP **)&pvar); //If the SAFEARRAY consists of a single VARIANT that is of type VT_ARRAY then //We want to call SafeArrayToVector using the embedded array. if(pvar[0].vt & VT_ARRAY) { SafeArrayToVector(pvar->parray, vecargs); } else SafeArrayToVector(*args, vecargs); SafeArrayUnaccessData(*args); } else SafeArrayToVector(*args, vecargs); std::vector::iterator it; int count = vecargs.size(); vector argsarray(count); USES_CONVERSION; for(it = vecargs.begin(), count = 0; it != vecargs.end(); it++, count++) { if((*it).vt & VT_BSTR) { if((*it).vt & VT_BYREF) argsarray[count] = reinterpret_cast(OLE2T(*(*it).pbstrVal)); else argsarray[count] = reinterpret_cast(OLE2T((*it).bstrVal)); } else if((*it).vt & VT_I4 || (*it).vt & VT_I2) { if((*it).vt & VT_BYREF) argsarray[count] = reinterpret_cast(*(*it).plVal); else argsarray[count] = reinterpret_cast((*it).lVal); } } LPTSTR lpMsgBuf; DWORD messageflags = FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY ; DWORD retval; //Format the message from the format string. retval = FormatMessage( messageflags, OLE2T(formatstring), NULL, LANG_SYSTEM_DEFAULT, (LPTSTR) &lpMsgBuf, 0, (va_list*)&argsarray[0] ); i

              R Offline
              R Offline
              Rajkumar R
              wrote on last edited by
              #9

              balakrishnan vinchu wrote:

              *outputstring = message.Detach();

              you already taken the ownership of the BSTR, created and associated with the CComBSTR, by Detach method; hence CComBSTR is not expected to release the BSTR. If you are expecting so then you are not supposed to return that buffer as out parameter (outputstring). this outputstring is not released and i think, so the tool you used to detect memory leak points to the creator of it, CComBSTR message(lpMsgBuf);.

              B 1 Reply Last reply
              0
              • B balakrishnan vinchu

                I changed my code as you explained in previous mail. LPTSTR lpMsgBuf = NULL; DWORD messageflags = FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY ; DWORD retval; //Format the message from the format string. retval = FormatMessage( messageflags, OLE2T(formatstring), NULL, LANG_SYSTEM_DEFAULT, lpMsgBuf, // Suggested to pass simply lpMsgBug 0, (va_list*)&argsarray[0] ); if (!retval) return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); CComBSTR message(lpMsgBuf); *outputstring = message.Detach(); LocalFree(lpMsgBuf); Now i am not getting the Formatted message, since retval returned from FormatMessgae API is zero (i.e 0), Because of this CComBSTR message didn't created. Also if i wont initialize lpMsgBuf = NULL, then functions just gives exception. Give me some suggestion. Thanks

                Regards, Bala

                B Offline
                B Offline
                balakrishnan vinchu
                wrote on last edited by
                #10

                Is this the right way? LPVOID lpMsgBuf; DWORD messageflags = FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY ; DWORD retval; //Format the message from the format string. retval = FormatMessage( messageflags, OLE2T(formatstring), NULL, LANG_SYSTEM_DEFAULT, (LPTSTR) &lpMsgBuf, 0, (va_list*)&argsarray[0] ); if (!retval) return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); CComBSTR message; message = T2OLE(LPTSTR(lpMsgBuf)); message.CopyTo(outputstring); I modified LPTSTR lpMsgBuf; to LPVOID lpMsgBuf; And converted LPTSTR to LPOLESTR. Am i doing correct here? :-)

                Regards, Bala

                M 1 Reply Last reply
                0
                • B balakrishnan vinchu

                  I changed my code as you explained in previous mail. LPTSTR lpMsgBuf = NULL; DWORD messageflags = FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY ; DWORD retval; //Format the message from the format string. retval = FormatMessage( messageflags, OLE2T(formatstring), NULL, LANG_SYSTEM_DEFAULT, lpMsgBuf, // Suggested to pass simply lpMsgBug 0, (va_list*)&argsarray[0] ); if (!retval) return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); CComBSTR message(lpMsgBuf); *outputstring = message.Detach(); LocalFree(lpMsgBuf); Now i am not getting the Formatted message, since retval returned from FormatMessgae API is zero (i.e 0), Because of this CComBSTR message didn't created. Also if i wont initialize lpMsgBuf = NULL, then functions just gives exception. Give me some suggestion. Thanks

                  Regards, Bala

                  C Offline
                  C Offline
                  CPallini
                  wrote on last edited by
                  #11

                  You're right (and I was wrong...). Whenever you use FORMAT_MESSAGE_ALLOCATE_BUFFER you have to pass the address of the variable, hence your code was correct. :)

                  If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
                  This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke

                  1 Reply Last reply
                  0
                  • R Rajkumar R

                    balakrishnan vinchu wrote:

                    *outputstring = message.Detach();

                    you already taken the ownership of the BSTR, created and associated with the CComBSTR, by Detach method; hence CComBSTR is not expected to release the BSTR. If you are expecting so then you are not supposed to return that buffer as out parameter (outputstring). this outputstring is not released and i think, so the tool you used to detect memory leak points to the creator of it, CComBSTR message(lpMsgBuf);.

                    B Offline
                    B Offline
                    balakrishnan vinchu
                    wrote on last edited by
                    #12

                    Is this the right way? LPVOID lpMsgBuf; DWORD messageflags = FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY ; DWORD retval; //Format the message from the format string. retval = FormatMessage( messageflags, OLE2T(formatstring), NULL, LANG_SYSTEM_DEFAULT, (LPTSTR) &lpMsgBuf, 0, (va_list*)&argsarray[0] ); if (!retval) return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); CComBSTR message; message = T2OLE(LPTSTR(lpMsgBuf)); message.CopyTo(outputstring); I modified LPTSTR lpMsgBuf; to LPVOID lpMsgBuf; And converted LPTSTR to LPOLESTR. Am i doing correct here? [Smile]

                    Regards, Bala

                    R 1 Reply Last reply
                    0
                    • B balakrishnan vinchu

                      Is this the right way? LPVOID lpMsgBuf; DWORD messageflags = FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY ; DWORD retval; //Format the message from the format string. retval = FormatMessage( messageflags, OLE2T(formatstring), NULL, LANG_SYSTEM_DEFAULT, (LPTSTR) &lpMsgBuf, 0, (va_list*)&argsarray[0] ); if (!retval) return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); CComBSTR message; message = T2OLE(LPTSTR(lpMsgBuf)); message.CopyTo(outputstring); I modified LPTSTR lpMsgBuf; to LPVOID lpMsgBuf; And converted LPTSTR to LPOLESTR. Am i doing correct here? :-)

                      Regards, Bala

                      M Offline
                      M Offline
                      Mukesh Kumar
                      wrote on last edited by
                      #13

                      Is this working correctly now? :)

                      Mukesh Kumar Software Engineer

                      1 Reply Last reply
                      0
                      • B balakrishnan vinchu

                        Is this the right way? LPVOID lpMsgBuf; DWORD messageflags = FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY ; DWORD retval; //Format the message from the format string. retval = FormatMessage( messageflags, OLE2T(formatstring), NULL, LANG_SYSTEM_DEFAULT, (LPTSTR) &lpMsgBuf, 0, (va_list*)&argsarray[0] ); if (!retval) return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); CComBSTR message; message = T2OLE(LPTSTR(lpMsgBuf)); message.CopyTo(outputstring); I modified LPTSTR lpMsgBuf; to LPVOID lpMsgBuf; And converted LPTSTR to LPOLESTR. Am i doing correct here? [Smile]

                        Regards, Bala

                        R Offline
                        R Offline
                        Rajkumar R
                        wrote on last edited by
                        #14

                        the question is not about "message" variable how you clean up "outputstring" variable.

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Don't have an account? Register

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups