Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   FreePascal (https://www.delphipraxis.net/74-freepascal/)
-   -   Prozedur per Pointer aufrufen (https://www.delphipraxis.net/165289-prozedur-per-pointer-aufrufen.html)

romy 22. Dez 2011 08:46

Prozedur per Pointer aufrufen
 
Hi,

zuerst möchte ich an dieser stelle sagen das dies mein erster post in diesen Forum ist obwohl ich schon 2 Jahre registriert bin.

Auf die Gefahr hin das ich hier im falschen Forum bin, schon zehntausend antworten auf mein Problem gibt frage ich trotzdem.

Ich habe ein Pointer Array:
Delphi-Quellcode:
 
FunktionsMR = Array [0..65535] of Pointer;
Die variable wird so deklariert

Delphi-Quellcode:

FunktionMR : funktionsMR;
Im Index 52880 kommt ein Pointer von einer Prozedur:

Delphi-Quellcode:

FunktionMR[52880] := @_StringSplit;
am Anfang habe ich das ganze so aufgerufen
Delphi-Quellcode:
TMethod(Event).Code := FunktionMR[52880];
TMethod(Event).Data := Self;
Button1.OnClick := Event;
Button1.Click;
das hat aber zu Problemen geführt und außerdem sollte das eine non GUI Anwendung, darum bin ich auf diese Methode umgestiegen

Delphi-Quellcode:

Call(FunktionMR[52880]);
die Call Prozedur sieht so aus:

Delphi-Quellcode:

procedure Call(dummy: pointer);
var
x : pointer;
begin
x := dummy;
asm
CALL x //<----- chrash
end;
end;
Nun ist es aber so ich kann das ganze mit dem pointer FunktionMR[52880] genau einmal aufrufen dann chrasht mir alles zusammen.

Was aber seltsam ist eine Prozedur mit dem pointer FunktionMR[48404] (ArrayDisplay) kann ich so oft aufrufen wie ich will.

Wieso ist das so, mache ich was falsch oder kann ich das ganze irgendwie besser verpacken?

Die Adresse im pointer wurde zugewiesen und stimmt das habe ich mehrmals nachgeprüft.

Ganz so steht es nicht im Quellcode aber das resultat ist das gleiche.

Ich bitte um Hilfe vornherein schon mal ein Riesen danke ihr seid spitze ohne euch wäre ich noch nicht so weit.

MfG

Romy <-- Legasthenikerin bitte um Rücksicht.

PS. die Delphi tags sind echt blöd hab eine halbe Stunde mit den Zeilenumbrüchen gekämpft.

Neutral General 22. Dez 2011 09:14

AW: Prozedur per Pointer aufrufen
 
Hallo,

Ist _StringSplit eine Prozedur oder eine Methode?
Und hat _StringSplit Parameter?

Das müsstest du natürlich beim Aufruf über Assembler beachten.

romy 22. Dez 2011 09:27

AW: Prozedur per Pointer aufrufen
 
Hi,

_StrinSplit hat im dem Sinne keine Parameter die übergeben werden müssem.
Die Parameter werden vorher von einen kleinen selbst Entworfenen Stack gepusht und in _StringSplit gepop. (wie raffiniert von mir^^).
Nur so am Rande wenn es hilft. soll eine kleine Scriptsprache werden und die Parameter werden in Parser gepusht.

Delphi-Quellcode:
procedure _StringSplit; //split: string; d: PChar; d darf nur ein einzelnes zeichen sein
var
   counter, i :Integer;
   
        split ,d: string;
        return: arrayresult; //array of string
begin
   d := pop;
   split := pop;
   counter := 0;
   split := split + d;
   SetLength(return,countstring(d,split)+1);
   for i := 1 to length(split) do
   begin
       if split[i]= d then
               counter :=counter+1;
   end;
   for i := 1 to length(split) do
   begin
      return[i]:= copy(split,0,pos(d,split)-1);
      delete(split,1, pos(d,split));
   end;
   return[0] := inttostr(counter);
   push(return); // das array
   push(counter); // größe des arrays
end;
genau so steht _StringSplit im Code

JamesTKirk 22. Dez 2011 13:32

AW: Prozedur per Pointer aufrufen
 
Zitat:

Zitat von romy (Beitrag 1142659)
Ich habe ein Pointer Array:
Delphi-Quellcode:
 
FunktionsMR = Array [0..65535] of Pointer;
Die variable wird so deklariert

Delphi-Quellcode:

FunktionMR : funktionsMR;
Im Index 52880 kommt ein Pointer von einer Prozedur:

Delphi-Quellcode:

FunktionMR[52880] := @_StringSplit;

Stehen in dem Array nur Prozeduren drin oder auch andere Werte?

Zitat:

Zitat von romy
Delphi-Quellcode:
TMethod(Event).Code := FunktionMR[52880];
TMethod(Event).Data := Self;
Button1.OnClick := Event;
Button1.Click;
das hat aber zu Problemen geführt und außerdem sollte das eine non GUI Anwendung, darum bin ich auf diese Methode umgestiegen

Das ist auch nicht gut, was du da machst, da
1. beim Code einer TMethod noch der Self Parameter versteckt mit übergeben wird und den deine Prozedur nicht berücksichtigt, da sie keine Methode einer Klasse ist (=> Probleme mit Stack und/oder Registern)
2. OnClick erwartet eine Methode, welchen eine Parameter enthält und übergibt diesen auch freudig (=> ähnliches Problem wie bei 1.)

Delphi-Quellcode:

Call(FunktionMR[52880]);
Probier doch mal

Delphi-Quellcode:
TProcedure(FunktionMR[52880])();
// die Klammern am Ende sind bei Free Pascal im Modus ObjFPC nötig,
// damit der Compiler weiß, dass es sich um einen Prozedurenaufruf handelt
Zitat:

Zitat von romy
die Call Prozedur sieht so aus:

Delphi-Quellcode:

procedure Call(dummy: pointer);
var
x : pointer;
begin
x := dummy;
asm
CALL x //<----- chrash
end;
end;
Nun ist es aber so ich kann das ganze mit dem pointer FunktionMR[52880] genau einmal aufrufen dann chrasht mir alles zusammen.

Einen Prozeduraufruf per Assembler würde ich an deiner Stelle nur durchführen, wenn ich mich vorher ein wenig mit Calling Conventions und ähnlichem beschäftigt hätte (und selbst dann nur mit äußerster Vorsicht).

Zitat:

Zitat von romy
Wieso ist das so, mache ich was falsch oder kann ich das ganze irgendwie besser verpacken?

Siehe meinen Vorschlag oben. Vielleicht möchtest du dich auch ein wenig zum Thema Prozedurvariablen belesen. Dazu verweise ich dich einfach mal hier zur Dokumentation von Free Pascal (nur in Englisch, ich hoffe das macht nichts).

Gruß,
Sven

romy 22. Dez 2011 14:35

AW: Prozedur per Pointer aufrufen
 
Hi,
danke das hat mein Problem gelöst, ihr seid echt spitze.

Zitat:


Delphi-Quellcode:
Delphi-Quellcode:

FunktionMR[52880] := @_StringSplit;
Stehen in dem Array nur Prozeduren drin oder auch andere Werte?

Dort stehen nur Prozeduren drin sonst nichts.

Kurze frage im Anschluss. Wenn ich das hier richtig verstanden habe dann ist das
Delphi-Quellcode:

type = TIrgendeineProzedur = procedure(x: integer); //
ein Typ den ich ganz vormal als Variable verwenden kann

Delphi-Quellcode:

var
  proc : TIrgendeineProzedur

Procedure printit (Var X : Integer);
begin
  WriteLn (x);
end;
 
begin
Proc := @printit;
end.
wie kann ich das ganze dann aufrufen? So geht es aber kommt nur Müll.
Delphi-Quellcode:
Proc := @printit;
TProcedure(proc)();
Was ist wenn das ganze eine Funktion wäre wohin kommt das Ergebnis?
Wenn ihr mir das noch erklärt kann ich meine wackelige Stack implentation loswerden.

MfG
Romy

JamesTKirk 22. Dez 2011 14:57

AW: Prozedur per Pointer aufrufen
 
Zitat:

Zitat von romy (Beitrag 1142743)
Zitat:


Delphi-Quellcode:
Delphi-Quellcode:

FunktionMR[52880] := @_StringSplit;
Stehen in dem Array nur Prozeduren drin oder auch andere Werte?

Dort stehen nur Prozeduren drin sonst nichts.

Wenn dort nur Prozeduren drinstehen, dann kannst du das Array auch folgendermaßen deklarieren:

Delphi-Quellcode:
FunktionsMR = Array [0..65535] of TProcedure;
Aufrufen kannst du ein Element dann einfach über
Delphi-Quellcode:
FunktionsMR[xyz]();
. Beachte aber bitte, dass das dann natürlich nicht funktioniert, wenn du dort Prozeduren reinsteckst, welche Parameter erwarten, oder auch Funktionen. Dann musst du wieder zu einem passenden Prozeduralen Typ casten (
Delphi-Quellcode:
TSomeProcType(FunktionsMR[xyz])(arg1, arg2);
).

Zitat:

Zitat von romy
Kurze frage im Anschluss. Wenn ich das hier richtig verstanden habe dann ist das
Delphi-Quellcode:

type = TIrgendeineProzedur = procedure(x: integer); //
ein Typ den ich ganz vormal als Variable verwenden kann

Jupp. Das hast du richtig verstanden.

Zitat:

Zitat von romy
Delphi-Quellcode:

var
  proc : TIrgendeineProzedur

Procedure printit (Var X : Integer);
begin
  WriteLn (x);
end;
 
begin
Proc := @printit;
end.
wie kann ich das ganze dann aufrufen? So geht es aber kommt nur Müll.
Delphi-Quellcode:
Proc := @printit;
TProcedure(proc)();

Hiermit machst du den selben Fehler, den ich bereits mit dem
Delphi-Quellcode:
TMethod
erwähnt habe. Du kannst eine Prozedurvariable wie eine normale Funktion aufrufen mit allem was dazu gehört (Parameter, Funktionswert):

Delphi-Quellcode:
var
  a: Integer;
begin
  a := 0;
  proc(a);
end;
Zitat:

Zitat von romy
Was ist wenn das ganze eine Funktion wäre wohin kommt das Ergebnis?

Genau wie bei einer normalen Funktion:

Delphi-Quellcode:
function AddFunc(aLeft, aRight: Integer): Integer;
begin
  Result := aLeft + aRight;
end;

type
  TBinaryIntFunc = function(aArg1, aArg2: Integer): Integer;

var
  func: TBinaryIntFunc;
  res: Integer;
begin
  func := @AddFunc;
  res := func(3, 5);
end;
Gruß,
Sven

romy 22. Dez 2011 15:34

AW: Prozedur per Pointer aufrufen
 
Hi,

Alle meinen Fragen sind beantwortet und ich bin jetzt um einiges glücklicher.

Ein riesiges Dankeschön klappt alles so wie ich wollte und sogar besser als je zuvor.

MfG
Romy

Eine letzte frage noch. Wie bekomme ich dieses "Offene Frage" in der Forenübersicht weg? Möchte niemanden verwirren.

JamesTKirk 22. Dez 2011 15:45

AW: Prozedur per Pointer aufrufen
 
Schön, dass ich dir helfen konnte.

Zitat:

Zitat von romy
Eine letzte frage noch. Wie bekomme ich dieses "Offene Frage" in der Forenübersicht weg? Möchte niemanden verwirren.

Da ist ein Häckchen unter "Zusätzliche Einstellungen", an dem steht "Dieses Thema als offene Frage markieren". Ich mach das Häckchen jetzt einfach mal raus und das sollte das dann hoffentlich erledigt haben.

Gruß,
Sven


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:40 Uhr.

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