AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen FreePascal FreePascal Unicode und WideChar API-Funktionen

Unicode und WideChar API-Funktionen

Ein Thema von Dalai · begonnen am 27. Mär 2023 · letzter Beitrag vom 12. Apr 2023
Antwort Antwort
Benutzerbild von himitsu
himitsu

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

AW: Unicode und WideChar API-Funktionen

  Alt 4. Apr 2023, 20:34
Also, wenn man mit Pointer rumpfuscht, anstatt PWideChar zu benutzen ... wenn irgendwann der Typ nicht mehr stimmt, dann beschwere dich bitte nicht, wenn der Compiler dir nichts sagen wird.

Warum wird hier ein UnicodeString an einen String (laut Hint in der Lazarus IDE ist String = AnsiString) zugewiesen?
Jemand hat vergessen zu sagen in welcher Zeile.
Ich rate mal.
Die Letzte? (mit dem Result:=)
Und nun überleg mal was du dort machst.

Delphi-Quellcode:
SetLength(Buffer, GetModuleFileNameW(Module, nil, 0));
GetModuleFileNameW(Module, PWideChar(Buffer), Length(Buffer)+1);
Aber wenn du sowie so kein Unicode haben willst, dann

Delphi-Quellcode:
function GetModuleName(Module: HMODULE): string; // oder eben UnicodeString und nachfolgend PWideChar
begin
  SetLength(Result, GetModuleFileName(Module, nil, 0));
  GetModuleFileName(Module, PChar(Result), Length(Result)+1);
end;
Im Delphi war String früher AnsiString und GetModuleFileName ein Alias für GetModuleFileNameA, bzw. PChar ein PAnsiChar,
und nun ist String ein UnicodeString und GetModuleFileName ein Alias für GetModuleFileNameW mit PWideChar.
Eventuell gibt es sowas mit dem genannten {$ModeSwitch UnicodeStrings} auch für Lazarus?



Delphi-Quellcode:
Result := Buffer;
Result := String(Buffer);
Mit Cast oder implitzt kommt erstmal das Gleiche bei raus, also vom Inhalt ... nur das Letzteres eben keine Cast-Warnung wirft.

Ich weiß nicht wie Lazarus/FPC das macht.
Vermutlich wie Delphi früher. Da wurde die Codepage des Types verwendet, also von der Variable.
Delphi seit 2009, hat die Codepage zusätzlich im String gespeichert und Verwendet vorzugsweise Dieses. (auch wenn man mal z.B. UTF-8 in einem "AnsiString" drin hat und nicht den UTF8String benutzte)



Zitat:
Currently the {$ModeSwitch UnicodeStrings} can be tested by defining "UseUTF16".
Vielleicht meinen die es andersrum?

vorher irgendwo {$ModeSwitch UnicodeStrings}
und später dann mit {$IFDEF UseUTF16} testen.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu ( 5. Apr 2023 um 02:25 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

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

AW: Unicode und WideChar API-Funktionen

  Alt 4. Apr 2023, 22:43
{$mode delphiunicode} sollte dir dabei gut weiterhelfen das alles so bleiben kann.
oder ein anderer ansatz, {$modeswitch m_default_unicodestring}
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.683 Beiträge
 
Delphi 5 Professional
 
#3

AW: Unicode und WideChar API-Funktionen

  Alt 11. Apr 2023, 23:18
{$mode delphiunicode} sollte dir dabei gut weiterhelfen das alles so bleiben kann.
Nein, das genügt nicht, siehe OP bzw. Beitrag #4. {$Mode DelphiUnicode} bzw. {$ModeSwitch UnicodeStrings} macht String zu UnicodeString, und (P)Char zu (P)WideChar. An den Imports der API-Funktionen ändert sich nichts, d.h. der Alias ExpandEnvironmentStrings verweist weiterhin auf ExpandEnvironmentStringsA statt ExpandEnvironmentStringsW.

Analog gilt das auch für die Klassen und Funktionen der Free Pascal RTL, wie man auch im von dir verlinkten Teil lesen kann. TIniFile und TFileStream kommen nach dem Umschalten nicht automatisch mit Unicode-Dateinamen bzw. -inhalten klar. Naja, vielleicht kommen sie schon damit klar (diese Frage ist ja weiterhin ungeklärt), aber es gibt beim Kompilieren Warnungen. Um die loszuwerden, muss man sich jeden einzelnen Aufruf anschauen und ändern, also eine andere Funktion rufen (z.B. UnicodeFormat statt Format), Casten oder Konvertierungsfunktion rufen. Das bedeutet, es kann eben nicht alles so bleiben.

Zitat:
oder ein anderer ansatz, {$modeswitch m_default_unicodestring}
Meintest du {$ModeSwitch UnicodeStrings} ?

Grüße
Dalai
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

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

AW: Unicode und WideChar API-Funktionen

  Alt 12. Apr 2023, 10:13
Ich habe mal für Dich im Lazarus Forum nachgefragt und die Antwort ist traurig, es geht schlichtweg nicht per switches oder conditionals.

Die einzige Möglichkeit ist es in der "Windows.pp" unit das hier einzufügen (was allerdings gegen die FPC/Lazarus Programmierung Arbeit, also ohne Gewähr!)

Patch:
Delphi-Quellcode:
{
    This file is part of the Free Pascal run time library.
    This unit contains the record definition for the Win64 API
    Copyright (c) 1999-2006 by Florian KLaempfl,
    member of the Free Pascal development team.

    See the file COPYING.FPC, included in this distribution,
    for details about the copyright.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

**********************************************************************}

unit windows;

{$PACKSET 1}

{$ifndef NO_SMART_LINK}
{$smartlink on}
{$endif}

{ stuff like array of const is used }
{$mode objfpc}
{$modeswitch ADVANCEDRECORDS}
{$modeswitch class}
{$inline on}
{$calling stdcall}

{$define FPC_OS_UNICODE} // <<<--- füge das ein

{$ifdef FPC_OS_UNICODE}
  {$define UNICODE}
{$endif}
getestet mit Lazarus 2.3.0 (rev 3bdbedd91b) FPC 3.2.2 x86_64-win64-win32/win64
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Unicode und WideChar API-Funktionen

  Alt 12. Apr 2023, 12:23
Die bräuchten ja doch nur für ihren Code (INC's) die passenden Unicode-Alternativen, welche über diesen Schalter umgeschaltet werden.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

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

AW: Unicode und WideChar API-Funktionen

  Alt 12. Apr 2023, 15:28
Mir wurde soeben eine bessere Variante gezeigt ohne das die RTL "angegriffen" wird und ich hoffe die ist okay für Deine Zwecke @Dalai
Delphi-Quellcode:
unit Unit1;
// basis settings um es unicode fähig zu machen
{$mode objfpc}
{$modeswitch unicodestrings}

interface

uses
  Windows , // ganz regulär integrieren
  Classes , SysUtils , Forms , Controls , Graphics , Dialogs;

// unicode hack teil 1/2
{$define read_interface}
{$undef read_implementation}
{$i C:\FreePascal\fpcsrc\rtl\win\wininc\unidef.inc}

type

  { TForm1 }

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
  public
  end;

var
  Form1: TForm1;

implementation

// unicode hack teil 2/2
{$undef read_interface}
{$define read_implementation}
{$i C:\FreePascal\fpcsrc\rtl\win\wininc\unidef.inc}

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
var
  lpApplicationName: PChar; // (PWideChar/LPCWSTR)
  lpBinaryType: LPDWORD;
begin
  GetBinaryType(lpApplicationName, lpBinaryType);
  // zeigt nun auf function GetBinaryType(lpApplicationName:LPCWSTR; lpBinaryType:LPDWORD):WINBOOL; external 'kernel32' name 'GetBinaryTypeW';
end;

end.
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.045 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#7

AW: Unicode und WideChar API-Funktionen

  Alt 12. Apr 2023, 16:09
Delphi 2009 hat angerufen und will seine Unicodeumstellung zurück
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.683 Beiträge
 
Delphi 5 Professional
 
#8

AW: Unicode und WideChar API-Funktionen

  Alt 12. Apr 2023, 20:35
Ich habe mal für Dich im Lazarus Forum nachgefragt und die Antwort ist traurig, es geht schlichtweg nicht per switches oder conditionals.
Danke fürs Nachfragen! Nach meinem bisherigen Eindruck ist die Situation wirklich traurig und unbefriedigend.

Zitat:
Die einzige Möglichkeit ist es in der "Windows.pp" unit das hier einzufügen (was allerdings gegen die FPC/Lazarus Programmierung Arbeit, also ohne Gewähr!)
Das FPC_OS_UNICODE kann man wahrscheinlich auch via "Additions and Overrides" in den Projektoptionen definieren. Eigentlich ist dieses Define aber für WinCE, was es nur als Unicode-OS gibt.

Mir wurde soeben eine bessere Variante gezeigt ohne das die RTL "angegriffen" wird und ich hoffe die ist okay für Deine Zwecke @Dalai
Beide Varianten helfen zwar für einige wenige Units, aber bei weitem nicht für alle und vor allem nicht für die Funktionen und Klassen der RTL. Für TStringList, TIniFile, TFileStream und wohl noch viele weitere ändert sich leider nichts. Und logischerweise ändert sich auch nichts, wenn eine RTL-Funktion explizit eine AnsiChar-API-Funktion ruft. All diese Sachen hab ich schon gesehen während der Konvertierung/Portierung eines meiner Projekte. Und das ist noch nicht einmal eines mit GUI. Keine Ahnung, wie die Situation mit Komponenten der LCL wäre.

Dennoch vielen vielen Dank für deinen Einsatz! Bin mal gespannt, wie lange es noch dauert, bis die Umstellung der Free Pascal RTL auf Unicode abgeschlossen ist ... Vielleicht vor dem Ende dieses Jahrzehnts?

Mittlerweile hab ich die Units eines meiner Projekte geändert auf UnicodeString und WideChar. Zum Testen genügt mir das. Mal sehen, ob ich die Entwicklung mit Free Pascal/Lazarus weiter verfolge.

Grüße
Dalai
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Unicode und WideChar API-Funktionen

  Alt 12. Apr 2023, 20:57
Lang lang ist's her.

als ich damals rein sah, gab es in RTL/VCL, bzw. den Quellen des FPC und des Lazarus einen Mischmasch aus ANSI und UTF8, mit einem Hauch von Unicode.


Die RTL kann man zu großen Teilen mit UTF-8 benutzen, also TStringList usw. (so lange intern keine krittischen APIs benutzt werden),
aber mindestens für die Schnittstelle vom/zum Windows (Win32-API), also auch die VCL, braucht es aber eben ANSI oder Unicode, da nicht alles UTF-8 versteht.

Den INI-Inhalt gibt es offiziell (Microsoft) nur als ANSI oder Unicode (UTF-16 und früher UCS-2),
aber so lange man die INI (Inhalt) nur selber benutzt ... UTF-8 ist ja auch eine Art von ANSI.

Nur der Dateiname für die INI/StringList muß eben ANSI oder Unicode sein. (UTF-8 will die ANSI-API nicht verstehen, denn die erwartet dort CP_ACP oder notfalls auch CP_OEM)
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (12. Apr 2023 um 21:03 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.683 Beiträge
 
Delphi 5 Professional
 
#10

AW: Unicode und WideChar API-Funktionen

  Alt 5. Apr 2023, 16:19
Also, wenn man mit Pointer rumpfuscht, anstatt PWideChar zu benutzen ... wenn irgendwann der Typ nicht mehr stimmt, dann beschwere dich bitte nicht, wenn der Compiler dir nichts sagen wird.
Ich dachte, es wäre klar gewesen (vor allem durch Angabe der Quelltextdatei), dass diese Funktion exakt so in den Sourcen von FPC steht. Deswegen auch meine Frage, warum die Funktion so aussieht.

Zitat:
Jemand hat vergessen zu sagen in welcher Zeile.
Ich rate mal.
Die Letzte? (mit dem Result:=)
Es gibt in dieser Funktion nur eine Zeile, wo ein UnicodeString an einen String zugewiesen wird - die Zuweisung an Result.

Zitat:
Und nun überleg mal was du dort machst.
Ich hab den Code nicht geschrieben, er ist 1:1 aus den Sourcen von FPC übernommen. Die Frage war, warum das dort so steht und ob die Warnung (bzgl. möglichem Datenverlust wegen UnicodeString -> String), die bei Übernahme der Funktion in eine eigene Unit auftaucht, gerechtfertigt ist.

Es sei noch ergänzt, dass ich die Funktion nur aus Neugier und Verwunderung ins eigene Projekt kopiert habe. Beim Lesen der Funktion tauchten sofort die Fragen auf, warum Pointer statt PWideChar benutzt wird und warum ohne Cast/Konvertierung ein UnicodeString an String zugewiesen wird. Ich wollte herausfinden, ob bzgl. des (Unicode)Strings eine Warnung auftaucht oder nicht. Sie taucht auf, und nun würde ich gern wissen, ob die berechtigt ist oder nicht.

Zitat:
Im Delphi war String früher AnsiString und GetModuleFileName ein Alias für GetModuleFileNameA, bzw. PChar ein PAnsiChar,
und nun ist String ein UnicodeString und GetModuleFileName ein Alias für GetModuleFileNameW mit PWideChar.
Das ist mir alles bekannt. Hier im Thread geht's aber explizit um Free Pascal.

Zitat:
Eventuell gibt es sowas mit dem genannten {$ModeSwitch UnicodeStrings} auch für Lazarus?
Das hatte ich ja am Anfang probiert, zwar mit {$Mode DelphiUnicode} , aber das Ergebnis ist dasselbe wie mit {$ModeSwitch UnicodeStrings} . Dabei hab ich festgestellt, dass die Funktionen/Klassen aus der FPC RTL eben nicht alle mit UnicodeString verfügbar sind. Das ist ja der Grund für den Thread hier und meine Fragen.

Zitat:
Delphi-Quellcode:
Result := Buffer;
Result := String(Buffer);
Mit Cast oder implitzt kommt erstmal das Gleiche bei raus, also vom Inhalt ... nur das Letzteres eben keine Cast-Warnung wirft.
Dass die Warnung unterdrückt wird, ist mir klar. Die Frage ist, ob man einfach so casten kann oder ob dadurch Zeichen kaputtgehen. Die Konvertierungsfunktionen (spätestens MultiByteToWideChar/WideCharToMultiByte in der Win32 API) existieren ja sicherlich auch nicht ohne Grund.

Zitat:
Ich weiß nicht wie Lazarus/FPC das macht.
Schade. Ich hoffe, jemand kann etwas zu diesem Punkt sagen.

Zitat:
Delphi seit 2009, hat die Codepage zusätzlich im String gespeichert und Verwendet vorzugsweise Dieses.
String ist doch seit 2009 ein UnicodeString. Inwiefern spielt dabei eine Codepage eine Rolle? Oder meinst du AnsiString?

Zitat:
Vielleicht meinen die es andersrum?

vorher irgendwo {$ModeSwitch UnicodeStrings}
und später dann mit {$IFDEF UseUTF16} testen.
Das glaube ich nicht. In der Unit LazUnicode kann man am Anfang Folgendes finden:
Delphi-Quellcode:
// For testing the UTF16 version.
{$IF DEFINED(FPC) and DEFINED(UseUTF16)}
 {$ModeSwitch UnicodeStrings}   // Sets also FPC_UNICODESTRINGS.
{$ENDIF}

{$IF DEFINED(FPC_UNICODESTRINGS) or not DEFINED(FPC)}
 {$DEFINE ReallyUseUTF16}       // FPC with UTF-16 or Delphi
{$ENDIF}
Und im Code dieser Unit wird dann an bestimmten Stellen {$IFDEF ReallyUseUTF16 benutzt.

Grüße
Dalai
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 08:05 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