Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Pointer auf TComponent versagt (https://www.delphipraxis.net/32699-pointer-auf-tcomponent-versagt.html)

CalganX 27. Okt 2004 13:02


Pointer auf TComponent versagt
 
Hi,
ich merke im Moment wie selten ich mich in den letzten Wochen mit Delphi beschäftigt habe. :lol:

Ich erhalte im Moment ständig eine Zugriffsverletzung und ich weiß nicht warum. :?
Der Fehler versteckt sich in folgender Methode:
Delphi-Quellcode:
function TIPlugin.Install(aApplication: IApplication): integer; stdcall;
var
  pComp: PComponent;
  cComp: TComponent;
  ehHandler: TEventHandler;
begin
  Result := NERROR_SUCCESS;
  ehHandler := TEventHandler.Create;
  try
    cComp := TComponent(aApplication.GetComponent('btnExport'));
    if ((cComp <> nil) and (cComp is TButton)) then begin
      (cComp as TButton).OnClick := ehHandler.OnBtnClick;
    end;

    gaApplication := aApplication;
  except
    Result := ERROR_UNKNOWN_ERROR;
  end;
end;
Entscheidende Rolle spielt dabei diese Methode, auf die zugegriffen wird:
Delphi-Quellcode:
function TIApplication.GetComponent(sComponentName: WideString): Pointer;
var
  pResult: PComponent;
  cComp: TComponent;
begin
  { Komponente des Forms finden und zurück an das Plugin geben }
  cComp := frmMain.FindComponent(sComponentName);
  pResult := @cComp;
  Result := pResult;
end;
Und zu guter Letzt sieht der Eventhandler so aus:
Delphi-Quellcode:
  TEventHandler = class
  public
    procedure OnBtnClick(Sender: TObject);
  end;

procedure TEventHandler.OnBtnClick(Sender: TObject);
var
  exExporter: TExportDataSet;
begin
  exExporter := TExportDataSet.Create;
  try
    exExporter.FileName := 'C:\Export.csv';
    exExporter.DataSet := TDataSet(gaApplication.GetDataSet);
    exExporter.Seperator := ';';
    exExporter.FixedLength := false;

    exExporter.ExportData;
  finally
    exExporter.Free;
  end;
end;
So... dise Zugriffsverletzung, die ich beim Aufrufen von TIPlugin.Install erhalte, kann ich nirgendwo aufspüren. Habe ich irgendwas übersehen?

Chris

mirage228 27. Okt 2004 13:12

Re: Pointer auf TComponent versagt
 
Hi,

versuch es mal, in dem Du
Delphi-Quellcode:
function TIPlugin.Install(const aApplication: IApplication): integer; stdcall;
schreibst.

Bei Interfaces entweder const oder var/out verwenden :)

mfG
mirage228

CalganX 27. Okt 2004 13:16

Re: Pointer auf TComponent versagt
 
Hi,
hat leider nicht funktioniert. :?

Chris

mirage228 27. Okt 2004 13:22

Re: Pointer auf TComponent versagt
 
Hi,

wie sieht es mit den "üblichen Verdächtigen" aus?

Also
  • Wird in GetComponent nicht nil zurückgeliefert? (Wozu eigentlich diese "Zwischenvariable" ?)
  • Versuch mal in Install erst dem pComp das Ergebnis zuzuweisen und das erst auf NIL zu überprüfen und erst anschließend casten
  • Versuch den Cast nach TComponent mal mit AS. Vorteil könnte sein, dass AS intern IS aufruft und somit prüft, ob da wirklich ein Zeiger auf TComponent zurückgegben wurde
  • An welcher Stelle tritt der Fehler genau auf?

mfG
mirage228

CalganX 27. Okt 2004 13:55

Re: Pointer auf TComponent versagt
 
Hi David,
Zitat:

Zitat von mirage228
Wird in GetComponent nicht nil zurückgeliefert? (Wozu eigentlich diese "Zwischenvariable" ?)

Nein. Zur Übersichtlichkeit. ;)

Zitat:

Zitat von mirage228
Versuch mal in Install erst dem pComp das Ergebnis zuzuweisen und das erst auf NIL zu überprüfen und erst anschließend casten

Hat nix gebracht.

Zitat:

Zitat von mirage228
Versuch den Cast nach TComponent mal mit AS. Vorteil könnte sein, dass AS intern IS aufruft und somit prüft, ob da wirklich ein Zeiger auf TComponent zurückgegben wurde

Versuch das mal mit einem Pointer. ;) Geht leider nicht. Vermutlich wegen der fehlende RTTI eines Pointers.

Zitat:

Zitat von mirage228
An welcher Stelle tritt der Fehler genau auf?

Gute Frage. Das Debuggen einer DLL ist etwas... nunja... umständlich. Und leider auch in meinem Fall nicht möglich...

Ich habe jetzt folgende Fehlerabfangroutinen:
Delphi-Quellcode:
begin
  Result := NERROR_SUCCESS;
  ehHandler := TEventHandler.Create;
  try
    try
      pComp := aApplication.GetComponent('btnExport');
    except
      Result := ERROR_INVALID_EXP;
      Exit;
    end;
    if pComp = nil then begin
      Result := ERROR_INVALID_POINTER;
      Exit;
    end;
    try
      cComp := TComponent(pComp);
    except
      Result := ERROR_INVALID_EXP;
      Exit;
    end;
    if cComp = nil then begin
      Result := ERROR_INVALID_COMPONENT;
      Exit;
    end;
    if (cComp is TButton) then begin
      (cComp as TButton).OnClick := ehHandler.OnBtnClick;
    end else begin
      Result := ERROR_INVALID_TYPE;
      Exit;
    end;

    gaApplication := aApplication;
  except
    Result := ERROR_UNKNOWN_ERROR;
    Exit;
  end;
Und was bekomme ich? - Genau eine Zugriffsverletzung bei der Zeile
Delphi-Quellcode:
case iPlg.Install(iApp) of
der Hauptanwendung. :wall:

Chris

mirage228 27. Okt 2004 13:57

Re: Pointer auf TComponent versagt
 
Du kannst doch in der Plugin DLL unter Start->Parameter die EXE angeben und dann auf Laden klicken. Breakpoints in der Plugin DLL (DPR) sollten dann angesprungen werden...

mfG
mirage228

CalganX 27. Okt 2004 14:00

Re: Pointer auf TComponent versagt
 
Hi,
in der DLL an sich steht aber nichts. ;) Das ganze ist in einzelnen Units ausgelagert. :zwinker:
Außerdem stürzt die Hostanwendung mit dem gleichen Fehler ab, weil bei dem jetzigen Source der Fehler ja schon beim Aufruf passiert. O.o

Chris

Christian Seehase 27. Okt 2004 15:08

Re: Pointer auf TComponent versagt
 
Moin Chris,

wozu soll das

Delphi-Quellcode:
pResult := @cComp;
eigentlich gut sein? :gruebel:

Das Ergebnis Deiner Methode ist dadurch die Adresse des Pointers der Komponente, und nicht die Komponente selber.
Also müsstest Du das Ergebnis von GetComponent dereferenzieren, damit es funktioniert:

z.B. so:

Code:
cComp := TComponent(aApplication.GetComponent('btnExport')[b][color=red]^[/color][/b]);
    if ((cComp <> nil) and (cComp is TButton)) then begin
      (cComp as TButton).OnClick := ehHandler.OnBtnClick;
    end;
oder so:

Code:
cComp := TComponent(aApplication.GetComponent('btnExport'));
    if ((cComp[b][color=red]^[/color][/b] <> nil) and (cComp[b][color=red]^[/color][/b] is TButton)) then begin
      (cComp[b][color=red]^[/color][/b] as TButton).OnClick := ehHandler.OnBtnClick;
    end;

CalganX 27. Okt 2004 15:54

Re: Pointer auf TComponent versagt
 
Hi Christian,
danke, das hat mir die Access-Violation vom Hals geschafft. :)

Allerdings bekomme ich jetzt ERROR_INVALID_COMPONENT zurück. :arrow: cComp ist nil. :?

Zu deiner Frage, wozu das gut sein soll: wenn ich TComponent zurückgebe bekomme ich doch Probleme mit der Unit ShareMem; sprich ich muss sie einbinden. Das will ich eigentlich vermeiden. ;)

Chris

CalganX 27. Okt 2004 16:40

Re: Pointer auf TComponent versagt
 
Hi,
habe jetzt ein wenig herumgesponnen und es geschafft ohne einen Pointer auf TComponent auszukommen.
Das funktioniert jetzt mit einigen kleinen Änderung. :)

Danke für eure Hilfe!

Chris

PS: Außerdem war der Name des Buttons falsch, aber das war noch ein anderes Problem. ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:28 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz