Run-Time Check Failure #0 - The value of ESP was not properly saved across a function

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Scieck
    New Member
    • Oct 2007
    • 10

    Run-Time Check Failure #0 - The value of ESP was not properly saved across a function

    Hi everyone !

    I got hold of a valid IWebBrowser2 object.
    I am passing it to a function that should return the value of href in a link tag in the IHTMLDocument3 object, here is the function:
    Code:
    LPCTSTR CInternetExplorer::GetHref(IWebBrowser2 *pWb)
    {
    	CString empty("");
    	CComQIPtr<IHTMLDocument3> doc3 = (IHTMLDocument3*)pWb;
    	if (doc3 == NULL)
    	{
    		return empty;
    	}
    	//CComQIPtr<IHTMLElementCollection> col;
    	//CComPtr<IHTMLElementCollection> col;
    	IHTMLElementCollection *col;
    	//CComBSTR link("LINK");
    	USES_CONVERSION;
    	BSTR link = A2BSTR("LINK");
    
    	HRESULT hr = doc3->getElementsByTagName(link, &col);   // <-- At this line i get the Run-Time Check Failure #0...
    
    	if (FAILED(hr)) return empty;
    	/*
    	   some more code here left out for clarity
         */
    	return empty;
    }
    Any ideas ?
    Many Thanks

    Andrea
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    This function returns an LPCTSTR and you are returning a CString.

    I'm surprised you are getting this to compile.

    Also, you are not using any of the TCHAR mappings in your code. That is, you should use CStringT and not Cstring. Your literals should use the TEXT macro, etc..

    I would create the BSTR by using SysAllocString or use CComBSTR rather than a macro.

    I assume your typecast in line 4 makes sense. I am susicious of all typecasts on COM interfaces that bypass IUnknown::Query Interface.

    Comment

    • Scieck
      New Member
      • Oct 2007
      • 10

      #3
      Hi weaknessforcats ,
      thank you for your reply.

      However you shouldn't be surprised the code compiles since the CString class has several overload operators that transform a CString to a LPCTSTR.
      Farther more a CString is basically a CStringT in fact it implements it, CStringT is a template class.

      I don't think the run-time error i am getting has any thing to do with the way a BSTR is created, and although you are suspicious regarding the use of CComQIPtr and CComPtr they exist to keep the code cleaner, more readable and bug free, references are automatically added and released.

      This is the full run-time error i am getting:
      Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

      I have tried with different Calling Conventions at compile time like /Gd and /Gz, and also i tried to declared the function with __stdcall no success so far.

      I am running out of options, any ideas ?

      Andrea

      Comment

      • Cucumber
        New Member
        • Sep 2007
        • 90

        #4
        Originally posted by Scieck
        Code:
        LPCTSTR CInternetExplorer::GetHref(IWebBrowser2 *pWb)
        {
        	CString empty("");
        	CComQIPtr<IHTMLDocument3> doc3 = (IHTMLDocument3*)pWb;
        Why arent you doing a QueryInterface on the IWebBrowser2 interface pointer to get an IHTMLDocument interface ptr, instead of that cast?

        Comment

        • Scieck
          New Member
          • Oct 2007
          • 10

          #5
          Hi Cucumber,
          good point, you're right:
          i changed the casting with this:
          Code:
          LPCTSTR CInternetExplorer::GetHref(IWebBrowser2 *pWb)
          {[INDENT]IDispatch *pDisp = NULL;[/INDENT][INDENT]HRESULT hr = pWb->get_Document(&pDisp);[/INDENT][INDENT]CComQIPtr<IHTMLDocument3> doc3(pDisp);[/INDENT][INDENT]// *****[/INDENT]
          The run-time error is gone.
          Many thanks !

          Andrea

          Comment

          • Scieck
            New Member
            • Oct 2007
            • 10

            #6
            Originally posted by weaknessforcats
            I assume your typecast in line 4 makes sense. I am susicious of all typecasts on COM interfaces that bypass IUnknown::Query Interface.
            Hi weaknessforcats ,
            your suspiciousness was totally right there.

            Thanks.

            Andrea

            Comment

            • weaknessforcats
              Recognized Expert Expert
              • Mar 2007
              • 9214

              #7
              Originally posted by scieck
              However you shouldn't be surprised the code compiles since the CString class has several overload operators that transform a CString to a LPCTSTR.
              Neat trick. You return a pointer to your CString that is a local variable and gets destroyed when the function completes??

              Comment

              • Scieck
                New Member
                • Oct 2007
                • 10

                #8
                Originally posted by weaknessforcats
                Neat trick. You return a pointer to your CString that is a local variable and gets destroyed when the function completes??
                This is exactly what happens.

                Comment

                • weaknessforcats
                  Recognized Expert Expert
                  • Mar 2007
                  • 9214

                  #9
                  Originally posted by scieck
                  This is exactly what happens.
                  So where is the string pointed at by the returned LPCTSTR?? And who cleans that up?

                  Comment

                  • Scieck
                    New Member
                    • Oct 2007
                    • 10

                    #10
                    [CODE=cpp]// returns the href attribute of a link tag given the rel attribute
                    // the first match is returned
                    // <link rel="stylesheet " type="text/css" href="style.css " />
                    LPCTSTR CInternetExplor er::GetLinkHref (IWebBrowser2 *pWb, const CString &rel)
                    {
                    CString empty(_T(""));
                    if (pWb == NULL) return empty;

                    IDispatch *pDisp = NULL;
                    HRESULT hr = pWb->get_Document(& pDisp);
                    if (FAILED(hr)) return empty;

                    CComQIPtr<IHTML Document3> doc3(pDisp);
                    if (pDisp)
                    {
                    pDisp->Release();
                    pDisp = NULL;
                    }
                    if (doc3 == NULL) return empty;

                    CComPtr<IHTMLEl ementCollection > col;
                    CComBSTR link("LINK");
                    hr = doc3->getElementsByT agName(link, &col);
                    if (FAILED(hr) || (col == NULL)) return empty;

                    long size = 0;
                    hr = col->get_length(&si ze);
                    if (FAILED(hr)) return empty;

                    for (long i = 0; i < size; i++)
                    {
                    COleVariant index(i);
                    hr = col->item(index, index, &pDisp);
                    if (SUCCEEDED(hr))
                    {
                    CComQIPtr<IHTML LinkElement> l(pDisp);
                    if (pDisp)
                    {
                    pDisp->Release();
                    pDisp = NULL;
                    }
                    if (l == NULL) return empty;

                    CComBSTR r;
                    hr = l->get_rel(&r);
                    if (SUCCEEDED(hr) && (r == CT2A(rel)))
                    {
                    CComBSTR href;
                    hr = l->get_href(&href );
                    if (SUCCEEDED(hr))
                    {
                    return COLE2CT(href.m_ str);
                    }
                    }
                    }
                    }
                    return empty;
                    }
                    [/CODE]
                    Originally posted by weaknessforcats
                    So where is the string pointed at by the returned LPCTSTR?? And who cleans that up?
                    Above there is the whole function that is now working, there are no memory leaks, or stack corruptions.
                    The above function works because the string is empty, therefore the return pointer points to 0 or NULL, i couldn't return a non empty CString with LPCTSTR as the return type becase the return pointer would be invalid if the CString is allocated on the stack.

                    Comment

                    • weaknessforcats
                      Recognized Expert Expert
                      • Mar 2007
                      • 9214

                      #11
                      Originally posted by scieck
                      The above function works because the string is empty, therefore the return pointer points to 0 or NULL, i couldn't return a non empty CString with LPCTSTR as the return type becase the return pointer would be invalid if the CString is allocated on the stack.
                      So if the function always returns 0, then why return anything. Maybe the return should be void though personally I would use an HRESULT. Like return S_OK.

                      Comment

                      • Scieck
                        New Member
                        • Oct 2007
                        • 10

                        #12
                        Originally posted by weaknessforcats
                        So if the function always returns 0, then why return anything. Maybe the return should be void though personally I would use an HRESULT. Like return S_OK.
                        [code=cpp]/********** more code up here *****/
                        CComBSTR n;
                        hr = m->get_name(&n) ;
                        if (SUCCEEDED(hr) && (n == CT2A(name)))
                        {
                        CComBSTR content;
                        hr = m->get_content(&c ontent);
                        if (SUCCEEDED(hr))
                        {
                        // this macro return a LPCTSTR
                        return OLE2CT(content) ;
                        }
                        }
                        }
                        }
                        return empty;
                        [/code]
                        If a match is found the value of the href attribute of the link tag is returned.

                        Comment

                        Working...