Exception beim Aufruf eines Formulars mit eigener Klasse in der Create-Routine.
-
JeGr: Sorry, wenn ich mich nicht ganz verständlich ausgedrückt habe. Genau so habe ich es gemacht.
AndreasW: Hmmm, der Konstruktor soll einige Variablen der eigenen Klasse belegen und die Registry auslesen. Wenn ich Dich also richtig verstanden habe, soll ich im Konstruktor der Klasse nochmal den Konstruktor der Klasse aufrufen? So etwa:
MyClass:MyClass() { this->MyClass(); .... }
Oder hast Du den Konstruktor des Fensters gemeint?
Gruß
Udo
-
OK!
Kannst du denn deine eigene Klasse mal in ein neues Testprojekt einbinden
und versuchen, dort ein Objekt zu erzeugen.
Vielleicht hat ja die Klasse an sich schon ein Problem.
Kannst du evtl. mal den Code von deiner Klasse zeigen?
(es würden schon die Headerdatei und der Konstruktor-Aufruf genügen)
-
MyClass:MyClass() { this->MyClass(); ... }
Erklär mir mal einer wieso ihr den Konstruktor sich selber aufrufen lasst?
-junix
-
Original erstellt von junix:
**
Erklär mir mal einer wieso ihr den Konstruktor sich selber aufrufen lasst?
**Das ist wohl eines der ungelösten Rätsel dieser Welt...
-
O.K. ich geb Euch mal den Header-Code vom Formular und von der Klasse. Hier das Formular:
class Tmainwindow : public TForm { __published: // IDE-managed Components TTBDock *topdock; TTBXToolbar *TBXToolbar1; TTBXSwitcher *TBXSwitcher1; TTBXSubmenuItem *dateimenue; TTBXItem *TBXItem1; TTBDock *leftdock; TTBXDockablePanel *TBXDockablePanel1; TPanel *Panel2; TTBXStatusBar *statusbar; TPanel *Panel3; TTBDock *TBDock1; TTBDock *TBDock2; TTBXSubmenuItem *bearbeitenmenue; TTBXItem *TBXItem11; TTBXSeparatorItem *TBXSeparatorItem5; TTBXAlignmentPanel *TBXAlignmentPanel1; TTBXAlignmentPanel *TBXAlignmentPanel2; TTBXAlignmentPanel *TBXAlignmentPanel3; TTBXAlignmentPanel *TBXAlignmentPanel4; TTBXAlignmentPanel *TBXAlignmentPanel5; TTBDock *TBDock3; TTBDock *TBDock4; TTBXToolbar *TBXToolbar2; TTBXToolbar *TBXToolbar3; TTBXItem *TBXItem16; TTBXItem *TBXItem17; TTBXLabel *TBXLabel1; TLabel *kategorielabel; TTBXAlignmentPanel *TBXAlignmentPanel6; TVirtualStringTree *VirtualStringTree1; TTBXLabel *TBXLabel2; TTBXCheckBox *TBXCheckBox1; TTBXItem *TBXItem18; TTBXPopupMenu *TBXPopupMenu1; TTBXItem *TBXItem19; TTBXItem *TBXItem20; TTBXSubmenuItem *TBXSubmenuItem3; TTBXItem *TBXItem21; TTBXSeparatorItem *TBXSeparatorItem6; TTBXSeparatorItem *TBXSeparatorItem7; TFormStorage *FormStorage1; TImageList *Large; TImageList *Small; TPanel *Panel6; TTBXToolbar *events; TImageList *eventicons; TOleContainer *container; TTBXToolbar *TBXToolbar4; TTBXItem *TBXItem2; TTBXToolbar *kategorieleiste; void __fastcall VirtualStringTree1GetText(TBaseVirtualTree *Sender, PVirtualNode Node, TColumnIndex Column, TVSTTextType TextType, WideString &CellText); void __fastcall VirtualStringTree1GetImageIndex( TBaseVirtualTree *Sender, PVirtualNode Node, TVTImageKind Kind, TColumnIndex Column, bool &Ghosted, int &ImageIndex); void __fastcall VirtualStringTree1Click(TObject *Sender); void __fastcall TBXItem11Click(TObject *Sender); void __fastcall TBXItem17Click(TObject *Sender); void __fastcall TBXItem1Click(TObject *Sender); void __fastcall FormCreate(TObject *Sender); void __fastcall FormShow(TObject *Sender); private: // User declarations // Deklaration des MessageHandlers void __fastcall WmDropFiles(TWMDropFiles& Message); public: // User declarations __fastcall Tmainwindow(TComponent* Owner); void __fastcall Tmainwindow::catbuttonclick(TObject* Sender); void __fastcall Tmainwindow::modulebuttonclick(TObject* Sender); Variant oberflaeche; TAppInitialize *appreg; TTBXItem* lastbutton; Variant module; // Sets up the message handler BEGIN_MESSAGE_MAP MESSAGE_HANDLER(WM_DROPFILES,TWMDropFiles,WmDropFiles) END_MESSAGE_MAP(TForm) };
hier der Code der Klasse, die erzeugt werden soll:
#ifndef initializingH #define initializingH #include <Registry.hpp> #include <strutils.hpp> #include <stdio.h> #include <dir.h> #include "addfunctions.h" #include "plugins.h" #include "kategoriliste.h" class TAppInitialize:TRegistry { public: __fastcall TAppInitialize(){}; __fastcall Initialize(); __fastcall ~TAppInitialize(){}; HRESULT __fastcall GetServerList(); HRESULT __fastcall ShowCategories(); HRESULT __fastcall RegisterServer(AnsiString PluginFullPath); HRESULT __fastcall UnRegisterServer(AnsiString PluginFullPath); __property AnsiString ApplicationPath = { read = AppPath, write = AppPath }; __property AnsiString ServerPath = { read = ServPath, write = ServPath }; __property AnsiString ApplicationName = { read = AppName, write = AppName }; TList* RegisteredServer; TList* UnRegisteredServer; Tkatlist* Categories; private: HRESULT __fastcall RegisterServer(Tplugin* Plugin); HRESULT __fastcall UnRegisterServer(Tplugin* Plugin); typedef enum{regProof, regProofOnly, regOpen, regOpenOnly, regAppend, regAppendOnly, regDelete, regClose}TRegAccess; HRESULT __fastcall SetRegistryPath(AnsiString CurrPath, TRegAccess RegAccess); bool __fastcall RegistryPath(TStringList* CurrKeys); AnsiString __fastcall GetGUID(TLIBATTR *Attributes){return Sysutils::GUIDToString(Attributes->guid);}; AnsiString __fastcall GetGUID(TYPEATTR *Attributes){return Sysutils::GUIDToString(Attributes->guid);}; struct ffblk ffblk; AnsiString __fastcall FindFirstServer(); // Serversuchroutine (findfirst) AnsiString __fastcall FindNextServer(); // Serversuchroutine (findnext) HRESULT __fastcall RegServer(AnsiString ServerName); // Serverregistrierung HRESULT __fastcall DeRegServer(AnsiString ServerName); // Serverderegistrierung AnsiString AppPath; AnsiString ServPath; AnsiString AppName; };
Die "Anwendungsklasse" erzeugt wiederum ein paar kleiner Unterklassen, der Headercode für diese Klassen sieht so aus:
#ifndef pluginsH #define pluginsH #include <strutils.hpp> #include <stdio.h> #include <dir.h> #include <Classes.hpp> #include <Dialogs.hpp> #include <windows.h> #include <windowsx.h> #include "addfunctions.h" class Tplugin:public TList { public: __fastcall Tplugin(){}; __fastcall ~Tplugin(){}; HRESULT __fastcall SetServer(AnsiString server); //HRESULT __fastcall SetServer(GUID serverguid); AnsiString __fastcall GetFileName() {return servername;}; AnsiString __fastcall GetFilePath() {return serverpath;}; AnsiString __fastcall GetGUIDString() {return serverguidstring;}; GUID __fastcall GetGUID() {return serverguid;}; TServermodule* __fastcall GetModule(int index) {return (TServermodule*)this->Items[index];}; TServermodule* __fastcall GetModule(GUID guid); TServermodule* __fastcall GetModule(AnsiString name); HRESULT __fastcall RefreshServer() {return SetServer(serverfullname);} HRESULT __fastcall SaveEvents(); TVersion version; void __fastcall DeleteItems(); private: AnsiString serverfullname; AnsiString servername; AnsiString serverpath; AnsiString serverguidstring; GUID serverguid; BSTR serverwcharname; LPTYPELIB typelibrary; TLIBATTR* tlibattr; IDispatch* coclassdispatch; UINT tlbinfocount; HRESULT __fastcall buildcoclasses(); }; //--------------------------------------------------------------------------- #endif
Ich habs grad versucht. Selbst wenn ich den Konstruktor ohne Code lasse und nach dem Erstellen der Klasse eine Initialisierungsroutine für die Klasse (zum Belegen der Variablen, etc.) aufrufe, kommt die Zugriffsverletzung.
@Junix: Der Konstruktor der Klasse kann, soweit ich gesehen habe nicht direkt aufgerufen werden. Die Möglichkeit kann ich dann auch nicht nehmen.
-
du solltest unbedingt mal was an deinem stil ändern. wenn du so weiter programmierst, fliegst du früher oder später auf die schnauze.
helfen kann ich aber nicht
-
Darkheart: Geh nochmal zurück zu meinem Post. Lies ihn nochmal in Ruhe, lies deinen Code, versteh deinen Code, ragier nochmal.
Variant-Variablen solltest du vermeiden, Public-Variablen sind eine todsünde (Siehe FAQ)-junix
-
class TAppInitialize:TRegistry { public: __fastcall TAppInitialize(){};
Du initialisierst ja im Konstruktor gar nichts.
Ist das beabsichtigt?
Und warum verwendest du so viele Public-Variablen?
Bsp:public: TList* RegisteredServer; TList* UnRegisteredServer; Tkatlist* Categories;
Wann, wo und wie initialisierst du denn diese Variablen?
P.S. dein Programmierstil erscheint mir auch etwas wirr.
Versuch doch mal, das ganze etwas übersichtlicher zu gestalten.P.P.S. step mal mit dem Debugger durch dein Programm. Dann kannst du genau ermitteln, wo die Speicherzugriffsverletzung auftritt.
-
@JeGr: Den Konstruktor habe ich grad erst geändert. Die Funktion Initialize war vorher der eigentlich Konstruktor der Klasse. Sie belegt auch RegisteredServer und UnRegisteredServer und noch einige andere Variablen.
Die Step by Step-Methode funktioniert nicht. Der Fehler tritt mal in der mainform auf, mal im Code der Klasse und mal in einer Unit eines externen Packages, daß mit dem ganzen Vorgang überhaupt nix zu tun hat und gar nicht angesprochen werden dürfte. Selbst in der mainunit des Projekts, also nach Erstellung des Formulars ist er schon mal aufgetreten. Das ist es ja, ich habe keinen festen Anhaltspunkt, wo die Zugriffsverletzung wirklich entsteht. Und aus dem CPU-Editor lässt sich nichts herausfinden, da an der entsprechenden Stelle nur ????? stehen.@Junix: Ok, dann muß ich wohl doch alle Variableninhalte der einzelnen Klassen über Funktionen und properties holen.
[Edit:]: Junix, ich habe mir jetzt nochmal Deinen Artikel durchgelesen (in Ruhe!!!!). Du meinst also, die Zugriffsverletzung kommt deshalb zustande, weil in meinem Fall eine "Public"-Variable nicht richtig definiert bzw. noch nicht definiert oder belegt ist? Aber warum "wandert" dann die Zugriffsverletzung durch den Code?[ Dieser Beitrag wurde am 23.01.2003 um 14:02 Uhr von Darkheart editiert. ]
-
Nein, kann aber natürlich sein. Kann nur sagen halt dich an die Debugvorschläge von JeGr. er hat absolut recht. Rätselraten bringts ned.
Ich meinte nur bezüglich des Konstruktors den du aufrfust (this->MyClass() oder wie das Teil hiess.. sie oben in deinem Code-Snippet)
-junix
-
Ehrlich gesagt, wußte ich zu diesem Zeitpunkt nicht, daß man den Konstruktor gar nicht direkt aufrufen kann. Aber das hat sich ja jetzt auch erledigt.
Ich habe grade alle "Puplic"-Variablen abgeändert und gebe deren Werte jetzt über Properties und Funktionen zurück ( bin doch lernfähig *gggggg*). Da dürfte es jetzt keine Schwierigkeiten mehr geben. Allerdings spinnt das Programm immer noch. Die einzige Möglichkeit, die ich jetzt noch habe, ist, ich überprüfe mal das Filesystem bzw. die Funktionen, die auf die Dateien zugreifen. Nachdem ich in der Klasse zweimal auf die Files zurgreife, kann es sein, daß hier der Fehler auftritt.
Das Prop dabei ist nur, daß ich hierzu teilweise Windows-Routinen benutze (u.a. LoadTypeLib). Hoffe, daß ist ein Ansatz. Ansonsten nehm ich den ganzen Mist und lösche alles.
[Edit]: Ein Tool, mit dem ich den Zugriffsfehler direkt einschränken kann gibts nicht oder? Nachdem der Fehler wandert, wäre das vielleicht nicht schlecht. BCB hat leider nur den CPU-Viewer.
[ Dieser Beitrag wurde am 23.01.2003 um 15:06 Uhr von Darkheart editiert. ]
-
Ich habs !!!! Vergesst alles, was wir hier geschrieben haben. Und zwar ist folgendes. In der Anwendungsklasse wird eine Routine aufgerufen, die neue COM-Server in Windows registrieren soll. Und so wie es aussieht, entsteht genau hier der Fehler ! Ich werde mir das mal näher anschauen.
Danke an Alle!