Gleiche Procedure mit 2 Bezeichner

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Mathias
Beiträge: 6143
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Gleiche Procedure mit 2 Bezeichner

Beitrag von Mathias »

In C habe ich folgendes, eine externe Function und mit define wird eine Kopie davon gemacht.

Code: Alles auswählen

extern XmTextPosition XmTextGetTopCharacter(Widget widget);
....
#define XmTextGetTopPosition                XmTextGetTopCharacter
Geht dir auch irgendwie mit Pascal ?

Un Pascal sieht die Ursprüngliche Function so aus:

Code: Alles auswählen

function XmTextGetTopCharacter(widget:TWidget):TXmTextPosition;cdecl;external;
H2Pas hat dies so umgesetzt, was leider nicht geht.

Code: Alles auswählen

const
  XmTextGetTopPosition = XmTextGetTopCharacter;  
Hat jemand eine Lösung dafür ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
theo
Beiträge: 10461
Registriert: Mo 11. Sep 2006, 19:01

Re: Gleiche Procedure mit 2 Bezeichner

Beitrag von theo »

Es gibt sicher verschiedene Wege dafür.
Hier kann man es wahrscheinlich mit "external name" lösen.

Code: Alles auswählen

function XmTextGetTopCharacter(widget:TWidget):TXmTextPosition;cdecl;external;
function XmTextGetTopPosition(widget:TWidget):TXmTextPosition;cdecl;external name 'XmTextGetTopCharacter';

Mathias
Beiträge: 6143
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Gleiche Procedure mit 2 Bezeichner

Beitrag von Mathias »

Danke. hat funktioniert.
Jetzt habe ich noch gemerkt, für was man in der Praxis "name" bracht.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1423
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Gleiche Procedure mit 2 Bezeichner

Beitrag von fliegermichl »

Für normale Funktionen, die nicht aus einer externen Bibliothek stammen, kann man auch procedurale Variablen verwenden.

Code: Alles auswählen

type
 TMyProcedure = procedure(Param1 : integer; Param2 : string);
 
procedure Test(Id : integer; Name : string);

var
 p1 : TMyProcedure = @test;
 p2 : TMyProcedure = @test;
Parameter dieses Typs können auch an andere Prozeduren und Funktionen übergeben werden.

Mathias
Beiträge: 6143
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Gleiche Procedure mit 2 Bezeichner

Beitrag von Mathias »

Parameter dieses Typs können auch an andere Prozeduren und Funktionen übergeben werden.
Im Prinzip ist es das selbe wie bei der LCL mit den Onxxx Proceduren.

Ich hab enoch folgendes probiert,

Code: Alles auswählen

var
  tp:function(w:TWidget):TXmTextPosition cdecl= XmTextGetTopCharacter;
aber es kommt dann folgender Fehler:

Code: Alles auswählen

xmxm.pas(1500,49) Error: Incompatible types: got "XmTextGetTopCharacter(Pointer):LongInt; CDecl;" expected "<procedure variable type of function(Pointer):LongInt;CDecl>"
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Warf
Beiträge: 1907
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Gleiche Procedure mit 2 Bezeichner

Beitrag von Warf »

Bei Funktionspointern muss man halt aufpassen das die zur Laufzeit aufgelöst werden, nicht zur Kompilezeit. Also z.B. wenn ein Funktionspointer nil ist dann krachts zur laufzeit. Außerdem kann der Optimizer nicht so Späße machen wie inlinen.
Und das bis Funktionsreferenzen im Stable release sind, gibts auch immernoch die Nervtötende unterscheidung zwischen Funktionspointern, Methoden pointern und Nested Funktionspointern.

Von daher ist es bei sowas oft einfacher einfach nen wrapper zu machen:

Code: Alles auswählen

function Foo(x: Integer): Integer; // original

// Wrapper
function Bar(x: Integer): Integer; inline
begin
  Foo(x);
 end;

Mathias
Beiträge: 6143
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Gleiche Procedure mit 2 Bezeichner

Beitrag von Mathias »

@warf
Dies hätte ich zur Not auch gemacht.

Ich denke für mein Problem war die Lösung von Theo am elegantesten.

Ab und zu haben die #define-Makros von C/C++ auch Vorteile. Aber leider werden die dort zT. sehr überladen, so das man sie kaum noch lesen kann.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Warf
Beiträge: 1907
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Gleiche Procedure mit 2 Bezeichner

Beitrag von Warf »

Simple Substitutionsmakros (ohne Parameter) gehen im FPC auch:

Code: Alles auswählen

{$Macro on}

function Foo(x: Integer): Integer;
begin
  Result := x*2;
end;

{$Define Bar:=Foo}

begin
  WriteLn(Bar(4));
end.
Werden aber nicht außerhalb der enthaltenden Unit angewendet

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2634
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Gleiche Procedure mit 2 Bezeichner

Beitrag von m.fuchs »

Warf hat geschrieben:
So 26. Mär 2023, 20:46
Werden aber nicht außerhalb der enthaltenden Unit angewendet

Code: Alles auswählen

function Foo(x: Integer): Integer;
begin
  Result := x*2;
end;

function Bar(x: Integer): Integer;
begin
  Result := Foo(x);
end;

begin
  WriteLn(Bar(4));
end.
Auch außerhalb der Unit nutzbar. :mrgreen:
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Mathias
Beiträge: 6143
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Gleiche Procedure mit 2 Bezeichner

Beitrag von Mathias »

Warf hat geschrieben:
So 26. Mär 2023, 20:46
Simple Substitutionsmakros (ohne Parameter) gehen im FPC auch:

Code: Alles auswählen

{$Macro on}

function Foo(x: Integer): Integer;
begin
  Result := x*2;
end;

{$Define Bar:=Foo}

begin
  WriteLn(Bar(4));
end.
Werden aber nicht außerhalb der enthaltenden Unit angewendet
Hast das mit den unterschiedlichen Units schon probiert.
Vielleicht geht Bar:=unit.foo .
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Warf
Beiträge: 1907
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Gleiche Procedure mit 2 Bezeichner

Beitrag von Warf »

Das problem ist das Makros nur in der Unit gültig sind in der sie Definiert wurden. Ist bei C übrigens genauso, nur das C header files mit #include als Textdatei eingebunden werden, und somit das Makro in jeder datei die die .h datei included Repliziert wird.
Der Grund ist ganz einfach, durch einbinden von Units über "uses" werden Lediglich die Sprachkonstrukte die im Interface teil Definiert sind nutzbar gemacht. Makros sind teil des Präprozessors, und sind nicht direkt Sprachkonstrukte selbst, sondern sind zu dem Zeitpunkt zu dem das Unit interface veröffentlicht wird bereits aufgelöst.

PascalDragon
Beiträge: 823
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: Gleiche Procedure mit 2 Bezeichner

Beitrag von PascalDragon »

Warf hat geschrieben:
Mo 27. Mär 2023, 00:12
Das problem ist das Makros nur in der Unit gültig sind in der sie Definiert wurden. Ist bei C übrigens genauso, nur das C header files mit #include als Textdatei eingebunden werden, und somit das Makro in jeder datei die die .h datei included Repliziert wird.
Der Grund ist ganz einfach, durch einbinden von Units über "uses" werden Lediglich die Sprachkonstrukte die im Interface teil Definiert sind nutzbar gemacht. Makros sind teil des Präprozessors, und sind nicht direkt Sprachkonstrukte selbst, sondern sind zu dem Zeitpunkt zu dem das Unit interface veröffentlicht wird bereits aufgelöst.
Prinzipiell unterstützt FPC Cross-Unit-Makros, da dies für Mac Pascal Code benötigt wird. Allerdings ist dies nur für Units aktiviert, die den MacPas-Modus nutzen, um eventuellen Problemen mit TP/Delphi Code vorzubeugen (es kommt dabei auf den Modus der verwendenden Unit an, nicht auf den der verwendeten Unit). Erreicht wird dies darüber, dass Makros in separaten Symboltabellen in ihren Units abgelegt werden, die je Modus mit zum Symboltabellenstapel für Makros hinzugefügt werden oder nicht.
FPC Compiler Entwickler

Mathias
Beiträge: 6143
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Gleiche Procedure mit 2 Bezeichner

Beitrag von Mathias »

Bei externen Variablen geht es einiges einfacher als bei Proceduren.

Code: Alles auswählen

  var
    _XmSDEFAULT_FONT : Pchar;cvar;external libXm; { In Xmos.c  }

    XmDEFAULT_FONT :PChar absolute _XmSDEFAULT_FONT;
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten