![]() |
Delphi-Version: 5
Unterschied Exception.Create und CreateRes
Hallo,
in einer Bibliothek an der ich arbeite wird manchmals dieses Konstrukt benutzt:
Delphi-Quellcode:
und manchmal dieses:
raise EDECHashException.CreateRes(@sHashNoDefault);
Delphi-Quellcode:
Wo ist der Unterschied bzw. was sind die Vor- oder Nachteile des jeweiligen Konstruktes?
raise EDECHashException.Creates(sHashNoDefault);
sHashNoDefault ist dabei jeweils der selbe Resourcestring. Grüße TurboMagic |
AW: Unterschied Exception.Create und CreateRes
Ganz genau kann ich's jetzt nicht sagen,
Aber nimm das mit dem @, denn es zeigt direkt auf die Ressource-ID. Heißt, dass es richtig übersertzt wird, z.B. bei GNU-GetText oder mit den DLL-Ressourcen vom Delphi. Beispiel: Kompiliere ein Programm, verwende dafür die RTL/VCL-Packages und lege die Sprachresourcen neben die BPLs. rtl***.bpl rtl***.de rtl***.jp vcl***.bpl vcl***.de vcl***.jp usw. Vorher vielleicht noch auf Englisch umstellen C:\Program Files (x86)\Embarcadero\Studio\21.0\bin\BDSSetLang.exe und dann schauen was passiert, wenn du in einem deutschen Windows die .DE daneben liegen hast oder nicht. |
AW: Unterschied Exception.Create und CreateRes
Zitat:
Zitat:
![]() Der Unterschied liegt darin, dass der Ressource-String erst beim eigentlichen Zugriff aus den Ressourcen geladen wird. Das führt zu einer anderen Behandlung bei der Übersetzung: "Constant resourcestring references are resolved during initialization by System._InitResStrings. If you change the application language after that, e.g. by calling LoadResourceModule, then these references will not be updated." -- ![]() D.h. bei Create(sRessourceString) wird der Ressource String einmalig bei Programmstart geladen (und dabei ggf. die Übersetzung verwendet). Falls der User (oder das Programm) später auf eine andere Sprache umschaltet, wirkt sich das auf diese Strings nicht mehr aus. Bei CreateRes(@sRessourceString) wird er erst beim Aufruf geladen, also in der jeweils zu diesem Zeitpunkt ausgewählten Sprache. |
AW: Unterschied Exception.Create und CreateRes
Hallo,
danke für alle Antworten! Grüße TurboMagic |
AW: Unterschied Exception.Create und CreateRes
Zitat:
Delphi-Quellcode:
resourcestring
s = 'foo'; begin Exception.Create(s); Exception.CreateRes(@s);
Code:
Wenn man einen Resourcestring an einen string zuweist, baut der Compiler hier LoadResString ein, was zur Übersetzung zu diesem Zeitpunkt führt. Geht man in den Code von CreateRes, sieht man, dass dort auch LoadResString aufgerufen wird. Der Effekt ist also genau derselbe, mit dem kleinen Unterschied für den aufrufenden Code - schauen wir uns mal Code in einer Routine ein, die die eine oder die andere Version nutzt:
ExceptionCreate.dpr.13: Exception.Create(s);
0041C549 8D55EC lea edx,[ebp-$14] 0041C54C B840A34100 mov eax,$0041a340 0041C551 E85EEEFEFF call LoadResString 0041C556 8B4DEC mov ecx,[ebp-$14] 0041C559 B201 mov dl,$01 0041C55B A1D41E4100 mov eax,[$00411ed4] 0041C560 E8F3B2FFFF call Exception.Create ExceptionCreate.dpr.14: Exception.CreateRes(@s); 0041C565 B940A34100 mov ecx,$0041a340 0041C56A B201 mov dl,$01 0041C56C A1D41E4100 mov eax,[$00411ed4] 0041C571 E816B4FFFF call Exception.CreateRes
Delphi-Quellcode:
procedure A;
begin Exception.Create(s); end; procedure B; begin Exception.CreateRes(@s); end;
Code:
ExceptionCreate.dpr.13: begin
0041A348 55 push ebp 0041A349 8BEC mov ebp,esp 0041A34B 6A00 push $00 0041A34D 33C0 xor eax,eax 0041A34F 55 push ebp 0041A350 688DA34100 push $0041a38d 0041A355 64FF30 push dword ptr fs:[eax] 0041A358 648920 mov fs:[eax],esp ExceptionCreate.dpr.14: Exception.Create(s); 0041A35B 8D55FC lea edx,[ebp-$04] 0041A35E B840A34100 mov eax,$0041a340 0041A363 E84C10FFFF call LoadResString 0041A368 8B4DFC mov ecx,[ebp-$04] 0041A36B B201 mov dl,$01 0041A36D A1D41E4100 mov eax,[$00411ed4] 0041A372 E8E1D4FFFF call Exception.Create ExceptionCreate.dpr.15: end; 0041A377 33C0 xor eax,eax 0041A379 5A pop edx 0041A37A 59 pop ecx 0041A37B 59 pop ecx 0041A37C 648910 mov fs:[eax],edx 0041A37F 6894A34100 push $0041a394 0041A384 8D45FC lea eax,[ebp-$04] 0041A387 E850CEFEFF call @UStrClr 0041A38C C3 ret 0041A38D E952C5FEFF jmp @HandleFinally 0041A392 EBF0 jmp $0041a384 0041A394 59 pop ecx 0041A395 5D pop ebp 0041A396 C3 ret
Code:
Dadurch, dass die erste Version quasi so aussieht:
ExceptionCreate.dpr.18: begin
0041A398 55 push ebp 0041A399 8BEC mov ebp,esp ExceptionCreate.dpr.19: Exception.CreateRes(@s); 0041A39B B940A34100 mov ecx,$0041a340 0041A3A0 B201 mov dl,$01 0041A3A2 A1D41E4100 mov eax,[$00411ed4] 0041A3A7 E8E0D5FFFF call Exception.CreateRes ExceptionCreate.dpr.20: end; 0041A3AC 5D pop ebp 0041A3AD C3 ret
Delphi-Quellcode:
muss der Compiler hier eine temporäre string Variable anlegen, die er für das Ergebnis von LoadResString benötigt.
procedure A;
begin Exception.Create(LoadResString(@s)); end; Beim der CreateRes ctor passiert das dort. Mag augenscheinlich egal sein, aber vermutlich ist das exception erzeugen und raisen ja in einem else, was selten angelaufen wird und dann muss da nicht immer im Prolog und Epilog der Methode das extrazeug passieren (siehe: ![]() |
AW: Unterschied Exception.Create und CreateRes
Ich versteh' die tolle Analyse leider noch nicht ganz.
Was bedeutet das nun für mich? Ist die CreateRes variante also nicht wie behauptet in der Lage zur Laufzeit eine Änderung eines Ressourcenstrings "mitzumachen"? Heißt das, dass auch diese Variante nur den Inhalt des Ressourcenstrings nutzt der zum Ladezeitpunkt/Programmstart aktiv war? Ist diese Variante sogar ressourcentechnisch noch leicht ineffizienter? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:26 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-2025 by Thomas Breitkreuz