Problem mit _com_error



  • Hallo Zusammen,

    ich habe ein Problem mit einem _com_error. Compilieren funktioniert, beim Ausführen stürzt es ab.

    Ich nutze wxWidgets unter MSVC++ Express Edition

    Folgender Quelltext:

    HRESULT hr = DcApp.GetActiveObject(_uuidof(Dcad17::Application));
    DcApp->BringToTop();
    DcApp->Visible = true;
    DcDocs = DcApp->Documents();
    DcDoc = DcApp->GetActiveDocument();
    DcPts = DcDoc->CmdPoints();
    double x_start; double y_start; double z_start;
    wxMessageBox(wxT("Bitte den Startpunkt setzen"));
    DcPts->GetUserPoint(&x_start,&y_start,&z_start);
    double x[]={0.0,1.5};double y[]={0.0,2.5}; //double z=0.0;
    SAFEARRAY *PktArray;
    SAFEARRAYBOUND sab;
    sab.cElements = 6;
    sab.lLbound = 0;
    PktArray = SafeArrayCreate(VT_R8,1,&sab);
    for (int i=0; i<3; i++)
    	{
    		long j=3*i;
    	        SafeArrayPutElement(PktArray,&j,&x[j]);
    		j = j+1;
    		SafeArrayPutElement(PktArray,&j,&y[j]);
    		j = j+1;
    		double z=0.0;
    		SafeArrayPutElement(PktArray,&j,&z);
    	}
    DcPts->SetCommandPoints(2,&PktArray);
    DcCurve->Draw();
    SafeArrayDestroy(PktArray)
    

    Ich vermute einen Überlauf im SAFEARRAY.

    Das sind die Meldungen im Ausgabefenster:

    Eine Ausnahme (erste Chance) bei 0x7c812afb in TestSafeArray.exe: Microsoft C++-Ausnahme: _com_error an Speicherposition 0x0013e80c..
    Der Thread 'RPC-Rückrufthread' (0xf20) hat mit Code 0 (0x0) geendet.
    Eine Ausnahme (erste Chance) bei 0x7c812afb in TestSafeArray.exe: Microsoft C++-Ausnahme: [rethrow] an Speicherposition 0x00000000..
    Eine Ausnahme (erste Chance) bei 0x7c812afb in TestSafeArray.exe: Microsoft C++-Ausnahme: [rethrow] an Speicherposition 0x00000000..
    Eine Ausnahme (erste Chance) bei 0x774dc8ed in TestSafeArray.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00175048.
    Unbehandelte Ausnahme bei 0x774dc8ed in TestSafeArray.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00175048.

    Das ganze dient der Fernsteuerung eines Zeichenprogrammes.

    Die Beispiele im Developer Handbuch von DesignCAD sind allerdings für C++ Builder 4 und 5, MSVC++ 6 und natürlich VB6 und Delphi 4 und 5.
    Ich vermute für die COM-Automation bin ich auf Header aus dem MFC angewiesen. Die habe ich in der Express Edition 2008 nicht gefunden.

    Liegt es am SAFEARRAY oder fehlt mir eine Header-Datei odere mehrere?

    Was mache ich beim Quelltext-Posten falsch, daß er nicht im c++-Format angezeigt wird?

    Gruß

    zarathus


  • Mod

    Du hast doch einen Aray mit nur 6 Elementen angelegt, aber Du versuchst 9 darin zu speichern!



  • Du hast recht. Manchmal ist man aber auch mit Blindheit geschlagen.

    j wird ja fleißig hochgezählt und ermittelt sich aus i. Folglich darf i maximal 1 werden, dann wird j zu 5 und das array ist voll.

    aber ich habe noch eine Frage:

    ich benötige eine Variable vom Typ "Olevariant", D.h. in Delphi nennt sich dieser Typ so. Wie wird dieser Typ in C++ genannt?

    Gruß

    zarathus


  • Mod

    VARIANT
    besser CComVariant (ATL), oder _variant_t (interner COM Code vom Compiler erzeugt)



  • So, der Absturz ist beseitigt.

    Es lag nicht direkt am SAFEARRAY. Das Bauen von dem SAFEARRY führte dazu dass das CAD_Progrämmchen nicht richtig die Linie darstellte, tut es aber jetzt.

    Ich hatte einfach vergessen

    DcCurve = DcDoc->Curve();
    

    zu machen.

    Jetzt gibt es "nur" noch einen "weichen Fehler", der nur beim Ausführen des Programmes Innerhalb der IDE auftritt. Wenn ich aus dem Explorer heraus die EXE bemühe pasiert nix.

    Es öffnet sich ein Header namens "comip.h"
    Dort entsteht eine Unbehandelte Ausnahme bei 0x774dc8ed in TestSafeArray.exe
    0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00175048.

    Das kommt auch, wenn ich den ganzen Array-Trödel auskommentiere und den Quelltext verkürtzt laufen lasse:

    HRESULT hr = DcApp.GetActiveObject(_uuidof(Dcad17::Application));
    DcApp->BringToTop();
    DcApp->Visible = true;
    DcDocs = DcApp->Documents();
    DcDoc = DcApp->GetActiveDocument();
    DcPts = DcDoc->CmdPoints();
    double x_start; double y_start; double z_start;
    wxMessageBox(wxT("Bitte den Startpunkt setzen"));
    DcPts->GetUserPoint(&x_start,&y_start,&z_start);
    

    Wie gesagt, es passiert nix wenn ich die EXE "normal" starte. Irgendwas scheint da nicht ganz koscher zu sein...

    Ich vermute dass die COM-Geschichte nicht so ganz sauber ist. Wie schon erwähnt beziehen sich die Beispiele im Handbuch auf C++Builder 4/5 und VC++6. Da werden irgendwelche afx...-Header verwendet. Die gibt es nicht bei mir.

    Vielen Dank nochmal für die Hilfe.

    Gruß

    Zarathus


Log in to reply