ATL/COM: _com_error: "Unzulässiger Zugriff auf einen Speicherbereich."



  • (VC++6, NT 4)

    hallo,

    ich habe einen Test ATL Server, und einen Test ATL Client.
    Atl-Server hat folgende Methode:

    // Interface:
    [id(1), helpstring("Methode getString")] HRESULT getString([out, retval] BSTR str);
    // Implementierung:
    // Methode soll eine memeber (CString m_Message) zurück geben
    // die im Konstruktor mit "--- nothing ---" initialisiert wird
    STDMETHODIMP CHello::getString(BSTR str)
    {
       AFX_MANAGE_STATE(AfxGetStaticModuleState())
    
       str = m_Message.AllocSysString();
       _bstr_t bstr(str, false);
    
       CString stemp2(_T(""));
       W2A(bstr, stemp2.GetBuffer(256), 256);
       stemp2.ReleaseBuffer();
       stemp2.Format(stemp2, "ATL_Server msg: %s", stemp2);
       AfxMessageBox(stemp2);
    
       return S_OK;
    }
    

    ATL-Client benutzt den Server so:

    void CATL_ClientDlg::OnButtonTest()
    {
       BSTR bstr = NULL;
       CString stemp(_T("---------- an empty CString ----------"));
       bstr = stemp.AllocSysString();
    
       try
       {  // rufe Methode des ATL-Serversauf:
          m_IHello->getString(bstr);
    
          CString stemp2(_T(""));
          W2A(bstr, stemp2.GetBuffer(256), 256);
          stemp2.ReleaseBuffer();
          stemp2.Format(stemp2, "ATL_Client msg: %s", stemp2);
          AfxMessageBox(stemp2);
          //m_Message = bsTemp.operator const wchar_t *();
          //showCurrEvent(m_Message);
       }
       catch(_com_error& rExc)
       {
          CString sMsg;
          _bstr_t temp(rExc.Description());
          //temp = rExc.Description()
          //sMsg = temp.operator const wchar_t *();
          W2A(temp, sMsg.GetBuffer(256), 256);
          sMsg.ReleaseBuffer();
          //showCurrEvent(sMsg);
          AfxMessageBox(sMsg);
    
          if (sMsg.IsEmpty())
          {
             sMsg = "Returned error code is empty..\n\nSomething goes wrong =(";	
          }
    
          AfxMessageBox(sMsg);
       }
    
       if (bstr != NULL)
       {
          SysFreeString(bstr);
       }
    }
    

    Ich bekomme immer am Anfang nach dem Aufruf der Methode m_IHello->getString(bstr); Eine MessageBox, wo halt "--- nothing ---" steht, also der Wert meines CStrings (m_Message vom ATL-Server)
    Dann wird der catch Block ausgeführt, wobei die oben gennante Fehlermeldung steht.

    Was mache ich falsch?

    P.S. Ich will bloss eine Methode auf dem Server haben, die mir den Wert eines CStrings zurückgibt und Möglichkeit, sie vom Client aufzurufen.



  • Ich habe den Fehler gefunden. War eigentlich ziemlich bllöd.
    ich musste die Funktion meines Interfaces anders deklarieren:

    // ALT & FALSCH
    [id(1), helpstring("Methode getString")] HRESULT getString([out, retval] BSTR str)
    // RICHTIG
    [id(1), helpstring("Methode getString")] HRESULT getString([out, retval] BSTR *str)
    //-----------------
    // Beim COM-Client sollte muss dan die Funktion auch anders aufgerufen werden:
       ...   
       BSTR bstr = NULL;
    
       try
       {  // rufe Methode des ATL-Serversauf:
          bstr = m_IHello->getString();
          ...
    

    Dann funktioniert der ganze Kramm auch 🙂


Anmelden zum Antworten