-".po"-Datei in Programmcode integrieren

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Benutzeravatar
kralle
Lazarusforum e. V.
Beiträge: 1196
Registriert: Mi 17. Mär 2010, 14:50
OS, Lazarus, FPC: Manjaro Linux, Mint und Windows 10 ,Lazarus 3.99, FPC-Version: 3.3.1
CPU-Target: 64Bit
Wohnort: Bremerhaven
Kontaktdaten:

-".po"-Datei in Programmcode integrieren

Beitrag von kralle »

Moin,

auf dem "2. Norddeutschen Lazarustreffen" und auf der "Lazaruskonferenz 2024" hatten wir Sprachdateien als Thema.

Bei all den besprochenen Varianten, musste die ".po"-Datei immer im Programmverzeichnis liegen.
Gibt es einen Weg, die ganze Sprachdatei oder nur die genutzten Texte, fest in Programm einzubinden, so das man nur eine ausführbare Datei am Ende hat.

Mit freundlichen Gruß
Heiko
OS: Manjaro Linux, Linux Mint und Windows 10
FPC-Version: 3.3.1 , Lazarus 3.99
+ Delphi XE7SP1

Soner
Beiträge: 726
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: -".po"-Datei in Programmcode integrieren

Beitrag von Soner »

Schau dort mein Beitrag und von anderen.

Sieben
Beiträge: 289
Registriert: Mo 24. Aug 2020, 14:16
OS, Lazarus, FPC: Ubuntu Xenial 32, Lazarus 2.2.0, FPC 3.2.2
CPU-Target: i386

Re: -".po"-Datei in Programmcode integrieren

Beitrag von Sieben »

Siehe auch meinen Beitrag direkt darunter. Wenn du dem Link nachgehst, findest du alles, was du brauchst um sämtliche Übersetzungen in die ausführbare Datei zu integrieren.

Benutzeravatar
kralle
Lazarusforum e. V.
Beiträge: 1196
Registriert: Mi 17. Mär 2010, 14:50
OS, Lazarus, FPC: Manjaro Linux, Mint und Windows 10 ,Lazarus 3.99, FPC-Version: 3.3.1
CPU-Target: 64Bit
Wohnort: Bremerhaven
Kontaktdaten:

Re: -".po"-Datei in Programmcode integrieren

Beitrag von kralle »

Moin,

Ich habe mir die Texte durch gelesen und die Beispiele angeschaut, ist doch ein ganz schöner Aufwand.

Da die Texte z.B. auf den Button in der IDE ja richtig angezeigt werden, gibt es nicht einen Weg, diese richtigen Texte auszulesen und dann zu nutzen?
Die IDE weiß ja anscheinend auch bei anderen Komponenten, welche welchen Text sie wo findet und anzeigen muss.
Wenn ich z.B. einem Button zu Entwicklungszeit ein anderen Text zuweise, dann wird dieser in der IDE und in der ausführbaren Datei richtig angezeigt.
Man bräuchte also quasi "nur" in der IDE einen Button "Ersetze Textplatzhalter durch die aktuellen Texte- klar dann kann man hinterher keine Fremdsprachige Version
mehr davon machen, aber ich für meinen Teil, erstelle eh nur deutschsprachige Programme.

Gruß Kralle
OS: Manjaro Linux, Linux Mint und Windows 10
FPC-Version: 3.3.1 , Lazarus 3.99
+ Delphi XE7SP1

Sieben
Beiträge: 289
Registriert: Mo 24. Aug 2020, 14:16
OS, Lazarus, FPC: Ubuntu Xenial 32, Lazarus 2.2.0, FPC 3.2.2
CPU-Target: i386

Re: -".po"-Datei in Programmcode integrieren

Beitrag von Sieben »

Die IDE weiß ja anscheinend auch bei anderen Komponenten, welche welchen Text sie wo findet und anzeigen muss.
Dreimal darfst du raten, wie die IDE das macht... Probier doch meine Lösung einfach mal aus - der Aufwand ist wesentlich geringer als es sich zuerst anhören mag, vor allem, wenn du nur die LCLStrings übersetzen willst. Wenn du Fragen dazu hast, stelle sie am besten dort im Ursprungsthread.

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

Re: -".po"-Datei in Programmcode integrieren

Beitrag von Warf »

kralle hat geschrieben: Di 15. Okt 2024, 18:59 Bei all den besprochenen Varianten, musste die ".po"-Datei immer im Programmverzeichnis liegen.
Gibt es einen Weg, die ganze Sprachdatei oder nur die genutzten Texte, fest in Programm einzubinden, so das man nur eine ausführbare Datei am Ende hat.
Alles in die Resourcen zu packen kann Vorteile haben, wenn man z.B. eine portable Anwendung bauen will, bei der man nur die .exe braucht, hat aber auch ganz klar mehrere Nachteile.
Zum einen rein Technisch wird zum Ausführen die EXE in den Speicher geladen. D.h. wenn du mehrere Sprachen mitlieferst werden immer alle Texte im Speicher geladen, obwohl effektiv immer nur maximal eine gleichzeitig verwendet wird. Das beeinflusst damit natürlich auch die Ladezeiten. Zwar ist RAM billig und CPUs und Platten sind schnell, außerdem kann Paging und dynmisches Memory Mapping vom OS das ein wenig mitigieren, vergrößert aber dennoch den Fußabdruck deiner Anwendung ungemein.

Das nächste ist Updatebarkeit. Wenn deine Software einen online Updater hat, ist es absolut trivial einzelne Dateien zu Patchen. Wenn du alles in die Resourcen steckst muss man immer eine neue Version der Anwendung runter laden, auch wenn sich nur ein typo geändert hat. Schön kann man das bei FPCUp sehen, bei dem man wenn eine neue Lazarus Version rauskommt man die neue FPCUp Version runter laden muss, weil dort die Versionsnummern und Branches zum runterladen der Verionen in den Resourcen hart Kodiert sind.

Dateien mit vielen Resourcen werden auch gerne mal als Viren von Virenschutzprogrammen erkannt und in Quarantäne verschoben, weil viel Malware ihre "Payload" als Obfuscated/Verschlüsselte Resourcestrings einbetten. Eine Anwendung die also größtenteils aus Resourcen besteht ist damit also erst mal suspekt.

Und zu guter letzt musst du nicht alle Sprachen ausliefern. Du kannst die App alleine ausliefern und die kann dann live Sprachdateien runterladen wenn diese vom Nutzer gewünscht oder Benötigt werden. Grade wenn du eine App hast die du in sehr vielen Sprachen bereitstellen willst, ist das deutlich angenehmer als das jeder Nutzer 30 Sprachpakete runter lädt obwohl die allermeisten nur eine einzige Sprache brauchen/wollen. Genauso wenn du eine neue Sprache unterstützt, kannst du einfach die .po Datei als separaten Download anbieten, ohne das jemand die ganze App neu runterladen muss.

Alles in allem ists generell so das man versucht möglichst wenig in die Resourcen der Anwendung selbst zu stecken. Und die meisten Anwendungen heutzutage brauchen ja eh noch zusätzliche DLLs oder ähnliches (z.B. OpenSSL wenn du einen Updater mitliefern willst), sodass du sowieso nicht mehr eine Datei hast

Sieben
Beiträge: 289
Registriert: Mo 24. Aug 2020, 14:16
OS, Lazarus, FPC: Ubuntu Xenial 32, Lazarus 2.2.0, FPC 3.2.2
CPU-Target: i386

Re: -".po"-Datei in Programmcode integrieren

Beitrag von Sieben »

Grundsätzlich natürlich völlig richtig, und wenn ich mehrere Sprachen unterstützen möchte, würde ich auch den von dir vorgeschlagenen Weg gehen. Aber wenn es wie hier gerade mal um die LCL-Strings geht, vergrößert sich die ausführbare Datei halt um die 40,8kB der LCLStConsts.de.po. Bis 'ungemein' ist da mE noch'n bisschen Luft für weitere Dateien.

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

Re: -".po"-Datei in Programmcode integrieren

Beitrag von fliegermichl »

Warf hat geschrieben: Mi 16. Okt 2024, 09:49
kralle hat geschrieben: Di 15. Okt 2024, 18:59 Bei all den besprochenen Varianten, musste die ".po"-Datei immer im Programmverzeichnis liegen.
Gibt es einen Weg, die ganze Sprachdatei oder nur die genutzten Texte, fest in Programm einzubinden, so das man nur eine ausführbare Datei am Ende hat.
Alles in die Resourcen zu packen kann Vorteile haben, wenn man z.B. eine portable Anwendung bauen will, bei der man nur die .exe braucht, hat aber auch ganz klar mehrere Nachteile.
Zum einen rein Technisch wird zum Ausführen die EXE in den Speicher geladen. D.h. wenn du mehrere Sprachen mitlieferst werden immer alle Texte im Speicher geladen, obwohl effektiv immer nur maximal eine gleichzeitig verwendet wird.
...
Ich meine im Hinterkopf zu haben, daß nicht die gesamte EXE in den Speicher geladen wird. Zum testen habe ich ein Projekt mit einer sehr großen Resource (6MB) erstellt und gestartet.
Der Windows Taskmanager zeigt 2,8MB Speicherbedarf an. Dann habe ich die Resource wieder entfernt und hab den gleichen Speicherverbrauch.

Erst wenn die Resource mittels LoadResource geladen wird, steigt der Speicherverbrauch an.
Die Programmdatei ist natürlich entsprechend größer mit der Resource.

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

Re: -".po"-Datei in Programmcode integrieren

Beitrag von Warf »

fliegermichl hat geschrieben: Mi 16. Okt 2024, 12:43 Ich meine im Hinterkopf zu haben, daß nicht die gesamte EXE in den Speicher geladen wird. Zum testen habe ich ein Projekt mit einer sehr großen Resource (6MB) erstellt und gestartet.
Der Windows Taskmanager zeigt 2,8MB Speicherbedarf an. Dann habe ich die Resource wieder entfernt und hab den gleichen Speicherverbrauch.

Erst wenn die Resource mittels LoadResource geladen wird, steigt der Speicherverbrauch an.
Die Programmdatei ist natürlich entsprechend größer mit der Resource.
Ich weiß nicht wie es mit windows resources ist da die vom OS speziell behandelt werden, Lazarus Ressourcen sind aber einfach konstante Strings im Datensegment der Anwendung.

Und wie das da funktioniert ist durch paging. Die Datei wird in virtuellen Speicher gemapped (unter Unix siehe mmap man page) und die pages werden dann on demand geladen wenn die Seite angefasst wird.
Eine page ist 4kb und es ist nicht garantiert das alle strings schon in 4kb blocks aufgeteilt werden, daher kann es gut passieren das Seiten geladen werden weil andere Teile der page angefasst werden oder sich größere Ressourcen überlappen.

Sieben
Beiträge: 289
Registriert: Mo 24. Aug 2020, 14:16
OS, Lazarus, FPC: Ubuntu Xenial 32, Lazarus 2.2.0, FPC 3.2.2
CPU-Target: i386

Re: -".po"-Datei in Programmcode integrieren

Beitrag von Sieben »

Macht das OS dann auch ein automatisches 'unmap', wenn eine Zeitlang kein Zugriff mehr erfolgt?

Benutzeravatar
kralle
Lazarusforum e. V.
Beiträge: 1196
Registriert: Mi 17. Mär 2010, 14:50
OS, Lazarus, FPC: Manjaro Linux, Mint und Windows 10 ,Lazarus 3.99, FPC-Version: 3.3.1
CPU-Target: 64Bit
Wohnort: Bremerhaven
Kontaktdaten:

Re: -".po"-Datei in Programmcode integrieren

Beitrag von kralle »

Moin,

erst einmal Danke für die vielen sehr ausführlichen Informationen.
Sollte man sich echt in ein Musterprojekt bereit legen.

In meinem aktuellen Projekt war die Lösung viel einfacher:
ich habe in den Eigenschaften des "TButtonPanel" bei den einzelnen Button,
einfach den Punkt "DefaultCaption" deaktiviert und schon waren die Texte in meinen Fall, auf Deutsch.

Müsste ich mal schauen, ob das bei allen Komponenten möglich ist. oder jetzt nur bei diesem "TButtonPanel".

Gruß Heiko
OS: Manjaro Linux, Linux Mint und Windows 10
FPC-Version: 3.3.1 , Lazarus 3.99
+ Delphi XE7SP1

Soner
Beiträge: 726
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: -".po"-Datei in Programmcode integrieren

Beitrag von Soner »

Eine gute Lösung ist vielleicht, dass alle Strings aus Lazarus- und FPC-Units in PO-Dateien oder ähnliches wandern und Fpc/Lazarus abhängig von Einstellung mittels einer Kompilerdefinition richtige PO-Datei einbindet, z.B. so etwas:

Code: Alles auswählen

{$I lclstrconsts.{$I %LANG%}.lrs} //{$I %LANG%} ist neu, für de oder en ...
TranslateFromResource('lclstrconsts', {$I %LANG%});
Dann ist das die Hauptsprache des Programms ohne etwas zu tun.
Jeder könnte in seinem Programm/Komponente ähnliches machen. Zur zeit haben wir in jedem Programm standardmäßig eingebundene englische Übersetzungen, die niemand zieht.

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

Re: -".po"-Datei in Programmcode integrieren

Beitrag von Warf »

Sieben hat geschrieben: Mi 16. Okt 2024, 16:29 Macht das OS dann auch ein automatisches 'unmap', wenn eine Zeitlang kein Zugriff mehr erfolgt?
Grundsätzlich nein, aber dafür gibt es paging. Wenn der RAM voll läuft werden zuletzt verwendete Pages in den Pagefile geschrieben. Paging kann oftmals probleme machen, denn das Laden und Speichern auf die Platte ist sehr langsam, und da RAM mittlerweile spott billig ist, braucht man es eigentlich kaum bis gar nicht. Ich habs tatsächlich bei meinem Linux komplett deaktiviert, da ich 48 GB RAM hab, und wenn die voll laufen ist sowieso irgendwas ganz gewaltig am schief laufen, sodass es besser ist da das System crashen zu lassen und einen Neustart zu machen als alles um einen Faktor 1000 oder mehr zu verlangsamen in der Hoffnung das das irgendwie wieder recovern kann (was es meist nur schlimmer macht).

Aber ja, mit paging, wenn du eine Seite lang nicht mehr angefasst hast, wird sie auf die Platte geschrieben und ist damit raus aus dem Hauptspeicher

Antworten