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. COM
  4. CString and COM

CString and COM

Scheduled Pinned Locked Moved COM
c++comhelpquestion
8 Posts 4 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.
  • M Offline
    M Offline
    monrobot13
    wrote on last edited by
    #1

    I'm pretty new to COM programming so here goes my question. I've written a component that has some properties. One is written like

    STDMETHODIMP CPopClient::get_Response(BSTR *pVal)
    {
    *pVal = (BSTR) m_bsResponse; // m_bsResponse is a CComBSTR

    return S\_OK;
    

    }

    Would this be the correct way to use it

    IPop->get_Response (&message.AllocSysString ()); // message is a CString

    Thinking about this I see a problem in that if the CString is null then I'm not allocating anything. So I guess I'm needing to know how I would call the above property from MFC. Thanks. - Aaron

    R A F 3 Replies Last reply
    0
    • M monrobot13

      I'm pretty new to COM programming so here goes my question. I've written a component that has some properties. One is written like

      STDMETHODIMP CPopClient::get_Response(BSTR *pVal)
      {
      *pVal = (BSTR) m_bsResponse; // m_bsResponse is a CComBSTR

      return S\_OK;
      

      }

      Would this be the correct way to use it

      IPop->get_Response (&message.AllocSysString ()); // message is a CString

      Thinking about this I see a problem in that if the CString is null then I'm not allocating anything. So I guess I'm needing to know how I would call the above property from MFC. Thanks. - Aaron

      R Offline
      R Offline
      Rory Solley
      wrote on last edited by
      #2

      No, you need to use a BSTR implicitly. BSTR bstrVal; IPop->get_Response (bstrVal); Your get_Response() implementation should be responsible for allocating storage. Your "client" must therefore free the BSTR when its finished with it. So, remember to call something like: ::SysFreeString(bstrVal); Hope that helps!

      M 1 Reply Last reply
      0
      • M monrobot13

        I'm pretty new to COM programming so here goes my question. I've written a component that has some properties. One is written like

        STDMETHODIMP CPopClient::get_Response(BSTR *pVal)
        {
        *pVal = (BSTR) m_bsResponse; // m_bsResponse is a CComBSTR

        return S\_OK;
        

        }

        Would this be the correct way to use it

        IPop->get_Response (&message.AllocSysString ()); // message is a CString

        Thinking about this I see a problem in that if the CString is null then I'm not allocating anything. So I guess I'm needing to know how I would call the above property from MFC. Thanks. - Aaron

        A Offline
        A Offline
        Andrew Quinn AUS
        wrote on last edited by
        #3

        Aaron, If you're using #import for your COM object, then why not use the nice wrappers implemented for you. e.g.

        \_bstr\_t bstrValue = IPop->GetResponse();
        

        The wrapper tests for failed HRESULTS and also uses _bstr_t which handles Allocs and Deallocs for you. Hope this helps, Andy

        M 1 Reply Last reply
        0
        • A Andrew Quinn AUS

          Aaron, If you're using #import for your COM object, then why not use the nice wrappers implemented for you. e.g.

          \_bstr\_t bstrValue = IPop->GetResponse();
          

          The wrapper tests for failed HRESULTS and also uses _bstr_t which handles Allocs and Deallocs for you. Hope this helps, Andy

          M Offline
          M Offline
          monrobot13
          wrote on last edited by
          #4

          AndyQ wrote: _bstr_t bstrValue = IPop->GetResponse(); Can I use that even though the get_Response is implemeted with the return being a pointer parameter passed in, and the return is an HRESULT? Thanks for the information on the _bstr_t class. - Aaron

          A 1 Reply Last reply
          0
          • R Rory Solley

            No, you need to use a BSTR implicitly. BSTR bstrVal; IPop->get_Response (bstrVal); Your get_Response() implementation should be responsible for allocating storage. Your "client" must therefore free the BSTR when its finished with it. So, remember to call something like: ::SysFreeString(bstrVal); Hope that helps!

            M Offline
            M Offline
            monrobot13
            wrote on last edited by
            #5

            Thank you for the information. - Aaron

            1 Reply Last reply
            0
            • M monrobot13

              AndyQ wrote: _bstr_t bstrValue = IPop->GetResponse(); Can I use that even though the get_Response is implemeted with the return being a pointer parameter passed in, and the return is an HRESULT? Thanks for the information on the _bstr_t class. - Aaron

              A Offline
              A Offline
              Andrew Quinn AUS
              wrote on last edited by
              #6

              Aaron, If you are using #import you should get two files in the project directory, e.g. Pop.tli Pop.thi These are implementation and header files from the import process. Now you should get different versions of the same method calls. You'll have the 'raw' call that returns the HRESULT as you describe, but there should be another version that simplifies things, an example may look like:

              inline _bstr_t IPop::GetResponse( ) {
              BSTR _result;
              HRESULT _hr = get_Response(&_result);
              if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
              return _bstr_t(_result, false);
              }

              Look for the files in your project directory (or debug/release directory) and look through them. Hope this helps, Andy

              M 1 Reply Last reply
              0
              • A Andrew Quinn AUS

                Aaron, If you are using #import you should get two files in the project directory, e.g. Pop.tli Pop.thi These are implementation and header files from the import process. Now you should get different versions of the same method calls. You'll have the 'raw' call that returns the HRESULT as you describe, but there should be another version that simplifies things, an example may look like:

                inline _bstr_t IPop::GetResponse( ) {
                BSTR _result;
                HRESULT _hr = get_Response(&_result);
                if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
                return _bstr_t(_result, false);
                }

                Look for the files in your project directory (or debug/release directory) and look through them. Hope this helps, Andy

                M Offline
                M Offline
                monrobot13
                wrote on last edited by
                #7

                Ah, that makes a lot of sense now. I wasn't using #import, but that seems like a much better way to do it. I'll give that a go. Thanks very much for the help Andy. - Aaron

                1 Reply Last reply
                0
                • M monrobot13

                  I'm pretty new to COM programming so here goes my question. I've written a component that has some properties. One is written like

                  STDMETHODIMP CPopClient::get_Response(BSTR *pVal)
                  {
                  *pVal = (BSTR) m_bsResponse; // m_bsResponse is a CComBSTR

                  return S\_OK;
                  

                  }

                  Would this be the correct way to use it

                  IPop->get_Response (&message.AllocSysString ()); // message is a CString

                  Thinking about this I see a problem in that if the CString is null then I'm not allocating anything. So I guess I'm needing to know how I would call the above property from MFC. Thanks. - Aaron

                  F Offline
                  F Offline
                  f64
                  wrote on last edited by
                  #8

                  Hi Aaron, There is an error in the way you are returning the string, what you are doing is passing the address of the string contained on m_bsResponse to the caller, the problem there is if the instance of CPopClient is destroyed the client will end having an address to a string that is not longer valid. So, what you should do is create a copy of the string and return the address of the copy. Remember BSTR is a pointer to a wide character string, so BSTR * is a pointer to a pointer!!!

                  STDMETHODIMP CPopClient::get_Response(BSTR *pVal)
                  {
                  *pVal = m_bsResponse.Copy(); // m_bsResponse is a CComBSTR
                  return S_OK;
                  }

                  And the client should do something like this to call it

                  BSTR sResponse;
                  IPop->get_Response(&sResponse);

                  ... do something with the string

                  //Free the string
                  SysFreeString(sResponse);

                  Fabian

                  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