AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi GetLocaleInfo() Aufruf, ist es so richtig?
Thema durchsuchen
Ansicht
Themen-Optionen

GetLocaleInfo() Aufruf, ist es so richtig?

Ein Thema von KodeZwerg · begonnen am 2. Apr 2018 · letzter Beitrag vom 3. Apr 2018
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.557 Beiträge
 
Delphi 12 Athens
 
#1

AW: GetLocaleInfo() Aufruf, ist es so richtig?

  Alt 2. Apr 2018, 18:41
Zitat:
Delphi-Quellcode:
  buf := StrAlloc(10);
  if GetLastError() = ERROR_SUCCESS then
Was soll GetLastError liefern, wenn StrAlloc keinen Fehler lieferte?

Etwas Zufälliges und zwar "laut Definition" den Fehlercode irgendeiner WinAPI, welches davor als Letztes einen Fehler lieferte.


Genau darum steht auch niemals "Ergebnis siehe GetLastError,
sondern "prüfe Result und wenn was schief lief, dann siehe GetLastError".

Zitat:
Delphi-Quellcode:
if GetLocaleInfo(
       LOCALE_SYSTEM_DEFAULT,
       LOCALE_STHOUSAND,
       buf,
       10) <> 0 then Result := StrPas(buf);
   if GetLastError() <> ERROR_INSUFFICIENT_BUFFER then
Wenn GetLocaleInfo erfolgreich war, dann war in StrPas die letzte WinAPI, aber vielleicht kommt das Result auch von irgendeiner WinAPI von irgendwann weit davor.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu ( 2. Apr 2018 um 18:47 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: GetLocaleInfo() Aufruf, ist es so richtig?

  Alt 2. Apr 2018, 19:17
Danke nochmals für die korrekte Handhabung per Api @Zacherl, ich hatte den Ansatz eigentlich nur gepostet wegen voriger Aussage warum ich nicht auf Compiler-Meldungen achte, das hatte ich da auch wenn Code falsch ist
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: GetLocaleInfo() Aufruf, ist es so richtig?

  Alt 2. Apr 2018, 20:03
Könnte man Dein Beispiel auch so abändern oder ginge dabei wieder etwas schief?

Delphi-Quellcode:
function ThousandSeparator : String;
const
 Default = ','; // Bei Fehler ein Default Wert nutzen um Meldungen zu überspringen
var
  Buffer: PChar;
  BufferLen: Integer;
begin
  BufferLen := GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_STHOUSAND, nil, 0);
  if (BufferLen = 0) then
  begin
    Result := Default;
    System.SetLastError(ERROR_SUCCESS);
    Exit;
    // RaiseLastOSError;
  end;
  Buffer := StrAlloc(BufferLen);
  if (not Assigned(Buffer)) then
  begin
    Result := Default;
    System.SetLastError(ERROR_SUCCESS);
    Exit;
    // raise EOutOfMemory.Create('StrAlloc failed');
  end;
  try
    if (GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_STHOUSAND, Buffer, BufferLen) <> BufferLen) then
    begin
      Result := Default;
      if Assigned(Buffer) then StrDispose(Buffer);
      System.SetLastError(ERROR_SUCCESS);
      Exit;
      // RaiseLastOSError;
    end;
    Result := StrPas(Buffer);
  finally
    StrDispose(Buffer);
  end;
end;
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#4

AW: GetLocaleInfo() Aufruf, ist es so richtig?

  Alt 2. Apr 2018, 20:19
Würde soweit funktionieren. Die extra Abfrage bezüglich String freigeben kannst du dir aber sparen, da der finally Abschnitt in jedem Falle ausgeführt wird (selbst bei Exit ). Und MSDN-Library durchsuchenSetLastError lass am besten auch komplett weg.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)

Geändert von Zacherl ( 2. Apr 2018 um 20:37 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: GetLocaleInfo() Aufruf, ist es so richtig?

  Alt 2. Apr 2018, 21:36
Vielen Dank! Ich habe nun das Extra StrDispose() und die SetLastError() Aufrufe entfernt.
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.557 Beiträge
 
Delphi 12 Athens
 
#6

AW: GetLocaleInfo() Aufruf, ist es so richtig?

  Alt 3. Apr 2018, 00:13
Abgesehn davon, dass if Assigned(Buffer) then sowieso immer True geliefert hätte.
Und zusammen mit dem Finally wäre StrDispose dann doppelt ausgeführt worden.

Und MSDN-Library durchsuchenSetLastError lass am besten auch komplett weg.
Es heißt ja auch SetLastError und nicht LastState.
IMHO wäre SUCCESS laut Definition somit falsch.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu ( 3. Apr 2018 um 00:26 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: GetLocaleInfo() Aufruf, ist es so richtig?

  Alt 3. Apr 2018, 07:52
Mit dem "System.SetLastError(ERROR_SUCCESS);" wollte ich halt Verhindern das aus dem Programm heraus irgendwelche Fehler-Meldungen aufploppen könnten wenn die Funktion ThousandSeparator aufgerufen wird.
Die Delphi Hilfe über RaiseLastOSError brachte mich darauf.
Die Funktion soll nur ein Ergebnis abliefern aber nie einen Fehler, total transparent, so als ob es Sie nicht gibt.
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.375 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: GetLocaleInfo() Aufruf, ist es so richtig?

  Alt 3. Apr 2018, 08:08
Da mich die Exit-Anweisungen in dem Code gestört haben, musste ich einfach den Source umschreiben. Jedes der Exits hätten einfach in ein else gepasst.
Dabei ist mir dann aufgefallen, dass der Source insgesamt noch einfacher geschrieben werden kann, wenn man den Default-Wert als erstes setzt und nur noch die die Sachen stehen lässt, die diesen verändern würden. Das SetLasteError habe ich auch weg gelassen, da ich die Notwendigkeit an der Stelle nicht erkennen kann. Dabei ist dann dieses bisschen Source übrig geblieben:
Delphi-Quellcode:
function ThousandSeparator : String;
const
  Default = ','; // Bei Fehler ein Default Wert nutzen um Meldungen zu überspringen
var
  Buffer: PChar;
  BufferLen: Integer;
begin
  Result := Default;
  BufferLen := GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_STHOUSAND, nil, 0);
  if (BufferLen > 0) then
  begin
    Buffer := StrAlloc(BufferLen);
    if Assigned(Buffer) then
    begin
      try
        if (GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_STHOUSAND, Buffer, BufferLen) = BufferLen) then
        begin
          Result := StrPas(Buffer);
        end;
      finally
        StrDispose(Buffer);
      end;
    end;
  end;
end;
Der Source kann nach kürzer werden, wenn man die nicht notwendigen "begin" und "end" bei zwei der if-Abfragen weglässt.

Zu SetLastError und RaiseLastOSError:
Da hier ein Default-Wert gesetzt wird, sind diese beiden Anweisungen nicht erforderlich. Gäbe es keinen Default-Wert, könnte das Ergebnis undefiniert sein. Dann wären die Anweisungen möglicherweise sinnvoll.
Peter
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:17 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