Bug beim Kompilieren von Funktionen mit Tmenuitem

Für Fragen rund um die Ide und zum Debugger
Antworten
br_klaus
Beiträge: 244
Registriert: Do 21. Jan 2010, 22:33
OS, Lazarus, FPC: Windows Vista (L 0.9.31 FPC 2.5.1)
CPU-Target: 32Bit
Wohnort: z.z. Brasilien, sonst 82335 Berg-Leoni (südlich von München)

Bug beim Kompilieren von Funktionen mit Tmenuitem

Beitrag von br_klaus »

Hallo, hier bin ich mal wieder:

Ich habe im Interfaceteil diese Angaben (in Zeilen 1884-1886):

Code: Alles auswählen

function SetMenuItemInfo(p1: HMENU; p2: UINT; p3: BOOL; const p4: TMenuItemInfo): BOOL; stdcall;
function InsertMenuItem(p1: HMENU; p2: UINT; p3: BOOL; const p4: TMenuItemInfo): BOOL; stdcall;
function GetMenuItemInfo(p1: HMENU; p2: UINT; p3: BOOL; var p4: TMenuItemInfo): BOOL; stdcall;
und im Implementation-Abschnitt

Code: Alles auswählen

function SetMenuItemInfo(p1: HMENU; p2: UINT; p3: BOOL; const p4: TMenuItemInfo): BOOL; stdcall; external user32 name 'SetMenuItemInfoA';
function InsertMenuItem(p1: HMENU; p2: UINT; p3: BOOL; const p4: TMenuItemInfo): BOOL; stdcall; external user32 name 'InsertMenuItemA';
function GetMenuItemInfo(p1: HMENU; p2: UINT; p3: BOOL; var p4: TMenuItemInfo): BOOL; stdcall;external user32 name 'GetMenuItemInfoA';
und erhalte da beim Kompilieren die kuriose Error-Mitteilung:

Code: Alles auswählen

C:\KOL_\_KOL3.17\KOL_ansi.inc(2532,10) Error: function header doesn't match the previous declaration "procedure SetMenuItemInfo(LongWord;LongWord;LongBool;const TMenuitemInfo):LongBool; StdCall;"
C:\KOL_\_KOL3.17\KOL_ansi.inc(1884,10) Hint: Found declaration: procedure SetMenuItemInfo(LongWord;LongWord;LongBool;const MENUITEMINFO):LongBool; StdCall;
C:\KOL_\_KOL3.17\KOL_ansi.inc(2533,10) Error: function header doesn't match the previous declaration "procedure InsertMenuItem(LongWord;LongWord;LongBool;const TMenuitemInfo):LongBool; StdCall;"
C:\KOL_\_KOL3.17\KOL_ansi.inc(1885,10) Hint: Found declaration: procedure InsertMenuItem(LongWord;LongWord;LongBool;const MENUITEMINFO):LongBool; StdCall;
C:\KOL_\_KOL3.17\KOL_ansi.inc(2534,10) Error: function header doesn't match the previous declaration "procedure GetMenuItemInfo(LongWord;LongWord;LongBool;var TMenuitemInfo):LongBool; StdCall;"
C:\KOL_\_KOL3.17\KOL_ansi.inc(1886,10) Hint: Found declaration: procedure GetMenuItemInfo(LongWord;LongWord;LongBool;var MENUITEMINFO):LongBool; StdCall;
C:\KOL_\_KOL3.17\kol.pas(61857) Fatal: There were 8 errors compiling module, stopping
Da wird also in der Mitteilung gesagt "procedure Name(variable): Ergebnis; stdcall;", obwohl es ja eindeutig Funktionen sind!
Und zwar eigenartigerweise nur bei diesen drei (von Hunderten anderen) Funktionen, die MenuItem im Namen bzw TMenuItemInfo als Parameter haben. Kann mir einer erklären, wie das zustande kommt?

Habe eine ganz frische SnapshotVersion 1.1-37904 FPC 2.71 vom 10.7.2012


Übrigens, wenn ich statt TMenuItemInfo den entsprechenden Pointer nehme (oder ein DWORD), dann geht es:

Code: Alles auswählen

function SetMenuItemInfo(p1: HMENU; p2: UINT; p3: BOOL; const p4: PMenuItemInfo): BOOL; stdcall;
function InsertMenuItem(p1: HMENU; p2: UINT; p3: BOOL; const p4: PMenuItemInfo): BOOL; stdcall;
function GetMenuItemInfo(p1: HMENU; p2: UINT; p3: BOOL; var p4: PMenuItemInfo): BOOL; stdcall;
Nur muß man dann halt bei der letzten Funktion aufpassen, daß damit p4^ gemeint ist.

Es muß also irgendwie an dem TMenuitem liegen, daß dieser kuriose Error passiert.

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Bug beim Kompilieren von Funktionen mit Tmenuitem

Beitrag von Socke »

br_klaus hat geschrieben:Hallo, hier bin ich mal wieder:

Ich habe im Interfaceteil diese Angaben (in Zeilen 1884-1886):
[...]
und im Implementation-Abschnitt
[...]
Warum packst du nicht die gesamte Deklaration in den Interface-Teil? Das ist weniger fehleranfällig, als wenn du alles doppelt schreiben musst.

Code: Alles auswählen

C:\KOL_\_KOL3.17\KOL_ansi.inc(2532,10) Error: function header doesn't match the previous declaration "procedure SetMenuItemInfo(LongWord;LongWord;LongBool;const TMenuitemInfo):LongBool; StdCall;"
C:\KOL_\_KOL3.17\KOL_ansi.inc(1884,10) Hint: Found declaration: procedure SetMenuItemInfo(LongWord;LongWord;LongBool;const MENUITEMINFO):LongBool; StdCall;
Das ist doch relativ einfach: Die Parameterlisten sind unterschiedlich: Vergleiche letzten Parameter "TMenuitemInfo" versus "MENUITEMINFO". Hast du im Implementations-Abschnitt vielleicht noch weitere Units eingebunden?
br_klaus hat geschrieben:

Code: Alles auswählen

C:\KOL_\_KOL3.17\kol.pas(61857) Fatal: There were 8 errors compiling module, stopping
Nanu, wo sind denn die anderen Fehler hin?!

Noch ein ganz wichtiger Hinweis:
Diese Windows-Funktionen werden wohl kaum mit einem Record oder einem Zeiger auf einen Record arbeiten, je nachdem, wie dein Free Pascal Compiler sich entscheidet. Sie werden vermutlich immer Zeiger auf einen Record erwarten.

Der Parameter-Modifikator const übergibt in Free Pascal den Parameter nicht in jedem Fall als Referenz (Pointer) auf dem Stack (siehe Free Pascal Lanuage Reference Guide). Der Compiler kann sich frei entscheiden, ob der Parameter als Referenz oder als ganzes übergeben wird. Damit weicht der Free Pascal Compiler von Delphi ab; dieses Verhalten lässt sich aber mit dem Modifikator constref erzwingen.

Mein Vorschlag ist es, die Deklaration wie folgt zu ändern:

Code: Alles auswählen

// die Pascal-Variante (ein wenig compiler magic für die Pointer)
function SetMenuItemInfo(p1: HMENU; p2: UINT; p3: BOOL; constref p4: TMenuItemInfo): BOOL; stdcall; external user32 name 'SetMenuItemInfoA';
function InsertMenuItem(p1: HMENU; p2: UINT; p3: BOOL; constref p4: TMenuItemInfo): BOOL; stdcall; external user32 name 'InsertMenuItemA';
function GetMenuItemInfo(p1: HMENU; p2: UINT; p3: BOOL; var p4: TMenuItemInfo): BOOL; stdcall;external user32 name 'GetMenuItemInfoA';
// die Zeiger-Variante (hier ist jedem klar, was als Parameter erwartet wird und was auf den Stack gehört)
function SetMenuItemInfo(p1: HMENU; p2: UINT; p3: BOOL; p4: PMenuItemInfo): BOOL; stdcall; external user32 name 'SetMenuItemInfoA';
function InsertMenuItem(p1: HMENU; p2: UINT; p3: BOOL; p4: PMenuItemInfo): BOOL; stdcall; external user32 name 'InsertMenuItemA';
function GetMenuItemInfo(p1: HMENU; p2: UINT; p3: BOOL; p4: PMenuItemInfo): BOOL; stdcall;external user32 name 'GetMenuItemInfoA';
P.S.: Diese Funktionen sind bereits in der Unit jwawinuser (JEDI-Projekt) vorhanden und werden vom FPC mitgeliefert (auch wenn die recht neue Unterscheidung zwischen const und constref hier noch nicht umgesetzt ist).
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

br_klaus
Beiträge: 244
Registriert: Do 21. Jan 2010, 22:33
OS, Lazarus, FPC: Windows Vista (L 0.9.31 FPC 2.5.1)
CPU-Target: 32Bit
Wohnort: z.z. Brasilien, sonst 82335 Berg-Leoni (südlich von München)

Re: Bug beim Kompilieren von Funktionen mit Tmenuitem

Beitrag von br_klaus »

Ich habe eine ganz einfache Lösung gefunden.
Das Problem war nämlich, daß zuerst im Implemantationsteil die Funktionen ohne Parameter angegeben waren, nur mit der Nagabe des Namens in der externen Library. Da beschwerte sich natürlich der Compiler. Darum kopierte ich mühsam (schließlich mit einem Makro) den Funktionskopf mit den Parametern vom Interfaceteil.
Und da ergab sich dann nur bei diesen drei Funtionen (sie nehmen immer TMenuInfo) diese komischen, in sich unlogischen, Errormeldungen.

Die Lösung: wieder die alte Fassung (ohne Parameterliste) - und zu Beginn: {$mode delphi} !
also zB nur
function GetMenuItemInfo; external user32 name 'GetMenuItemInfoA';
jetzt geht es ohne Schwierigkeiten!

Übrigens beziehen sich die Angaben wie zB TMenuInfo etc. auf KOL, und da wird das Ganze ein wenig anders gehandhabt. Da gibt es ein riesiges TObj mit unzähligen Parametern, properties und Funktionen/Prozeduren, die auf eine ausgeklügelte Weise aufeinander folgen, sodaß viel mit Assembler gearbeitet werden kann. Von diesem TObj werden alle anderen Objekte abgeleitet. KOL benützt fast nur Zeiger (PObj) und kaum Klassen.
Der Effekt ist, daß Programme, die bei Lazarus 13 MB und mehr groß sind, mit KOL höchstens 500KB belegen (und entsprechend viel schneller starten).
Es lohnt sich, damit zu programmieren.

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Bug beim Kompilieren von Funktionen mit Tmenuitem

Beitrag von Socke »

br_klaus hat geschrieben:Der Effekt ist, daß Programme, die bei Lazarus 13 MB und mehr groß sind, mit KOL höchstens 500KB belegen (und entsprechend viel schneller starten).
Es lohnt sich, damit zu programmieren.
Von KOL hab ich schon einmal gehört (mehr aber auch nicht). Dass du Lazarus-Programme mit 13 MB Dateigröße erstellst, spricht wirklich komplexe Anwendungen oder für mangelnde Kenntnisse über die Debug-Informationen und Compiler-Schalter :P
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

br_klaus
Beiträge: 244
Registriert: Do 21. Jan 2010, 22:33
OS, Lazarus, FPC: Windows Vista (L 0.9.31 FPC 2.5.1)
CPU-Target: 32Bit
Wohnort: z.z. Brasilien, sonst 82335 Berg-Leoni (südlich von München)

Re: Bug beim Kompilieren von Funktionen mit Tmenuitem

Beitrag von br_klaus »

Socke hat geschrieben:
br_klaus hat geschrieben:Der Effekt ist, daß Programme, die bei Lazarus 13 MB und mehr groß sind, mit KOL höchstens 500KB belegen (und entsprechend viel schneller starten).
Es lohnt sich, damit zu programmieren.
Von KOL hab ich schon einmal gehört (mehr aber auch nicht). Dass du Lazarus-Programme mit 13 MB Dateigröße erstellst, spricht wirklich komplexe Anwendungen oder für mangelnde Kenntnisse über die Debug-Informationen und Compiler-Schalter :P
Ich würde sagen, beides. Ich habe meist sehr viele Units und kenne ich mich so gut wie überhaupt nicht mit Debug-Informationen und CompilerSchaltern aus.
Was kann man denn machen, um Dateien kleiner zu bekomen?

Herzlichen Dank.

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Bug beim Kompilieren von Funktionen mit Tmenuitem

Beitrag von Socke »

br_klaus hat geschrieben:Ich würde sagen, beides. Ich habe meist sehr viele Units und kenne ich mich so gut wie überhaupt nicht mit Debug-Informationen und CompilerSchaltern aus.
Was kann man denn machen, um Dateien kleiner zu bekomen?
Das ist eine wirklich häufig gestellte Frage. Schau dich hier mal im Forum um (google Suche, etc.); siehe auch: http://wiki.freepascal.org/Lazarus_Faq# ... _so_big.3F" onclick="window.open(this.href);return false;
Der einfachste Punkt ist, die Debug-Informationen aus der Programm-Datei zu entfernen. Danach gibt es noch weitere Mögichkeiten:
  • Code-Optimierungen durch den Compiler (unter Anderem Variablen, Stack-Frames, etc.)
  • Smart-Linking
  • Whole Program Optimization
Wobei für diese alle Teile des Programms entsprechend compiliert werden müssen: Dazu gehören neben deinem eigenen Quelltext auch die RTL, FCL und LCL.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Antworten