Forum > Beginners

3.0 RC2, Windows: non-unicode API by default?

(1/4) > >>

Nick:
I am just beginner in FPC (but some advanced in developing), so... :)
NTFS file-system is unicode, so there might be files with unicode characters, and are there, on people's disks. But we can't use them with default FPC settings.
If program uses TStringList.LoadFromFile then user get error on open file. Example: windows with US locale, and file name like "Имя в Юникоде.txt".
As a workaround we can rebuild fpc-libraries with FPC_OS_UNICODE, but this is workaround.
I think it will be useful to have unicode libraries too, in distro.

Thaddy:
I don't understand the problem:
FPC has about the richest set of string types available and to be more specific NTFS has never been any problem under Windows. There really is no need to recompile the whole with FPC_OS_UNICODE and it is not a workaround in that sense. The Unicode API's are fully accessible by means of the UnicodeString type, which is a Windows compatible UTF16 reference counted string type compatible with Delphi or C#.

Can you give us a small example where you ran into trouble?

I guess you are simply looking for a modeswitch ;) and indeed that is there:
Use {$modeswitch unicodestrings} or even better (since you are developing for Windows) use the {$mode delphiunicode} which switches the default string to a Delphi 2009+ compatible Unicode16 string.
"string" becomes an alias for "unicodestring"in these cases and the "XxxxW" windows Api's are called.

Also, Lazarus has an intermediate solution based on UTF8 by default.

If you ran into trouble, the most likely that happened is insufficient reading of the very good documentation.

There ARE good reasons to recompile with FPC_OS_UNICODE but these are not specifically related to Windows API's or NTFS (which is a special case of the former).

Nick:
I checked it out.

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program UnicodeTest1; {$H+}{$mode delphiunicode}{$modeswitch unicodestrings}{$define Unicode}{$define FPC_OS_UNICODE} uses  Classes, SysUtils, CustApp,  Windows; type  TMyApplication = class(TCustomApplication)  protected    procedure DoRun; override;  end; procedure CreateFileA; external 'kernel32' name 'CreateFileA';//procedure CreateFileW; external 'kernel32' name 'CreateFileW'; { TMyApplication } procedure TMyApplication.DoRun;begin  if @CreateFile = @CreateFileA then    WriteLn('Ansi API')  else    WriteLn('Unicode API'); //  WriteLn('SizeOf(Char) = ' + IntToStr(SizeOf(Char)));   WriteLn('Press enter...');  Readln;  // stop program loop  Terminate;end; var  Application: TMyApplication;begin  Application:=TMyApplication.Create(nil);  Application.Title:='My Application';  Application.Run;  Application.Free;end. Result: Ansi API

marcov:

--- Quote from: Nick on November 21, 2015, 06:28:00 pm ---
--- Quote ---  if @CreateFile = @CreateFileA then
    WriteLn('Ansi API')
  else
    WriteLn('Unicode API');

--- End quote ---

As the person that created FPC_OS_UNICODE, I still find it hard to understand the actual problem.

Whatever "createfile" is aliased too doesn't really matter much. Changing it to _W won't make everything automatically wide tolerant.3

So maybe take a step back and describe what is actually the problem.
--- End quote ---

Arvur:
This seems to be my case. First - the problem. I need compatibility with Delphi code (XE6) without massive modifications.

Documentation states it is real. So I set {$mode delphiunicode} (in project options and in the unit) and ... get lots of errors. They are of two types generally:

1. Error: Incompatible type for arg no. 6: Got "PWideChar", expected "PChar"

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function SearchFilePath(const FName: string) : string;var  i, Len: Integer;  P: PChar;begin  i := SearchPath(nil, PChar(FName), nil, Len, PChar(Result), P); I dig into SearchPath and see external 'kernel32' name 'SearchPathA' in ascdef.inc

2. Warning: Implicit string type conversion with potential data loss from "UnicodeString" to "RawByteString"

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---var  Dir: string;  SearchRec: TSearchRec;begin  if FindFirst(IncludeTrailingPathDelimiter(Dir) + '*.*', faAnyFile, SearchRec) = 0 then FindFirst falls back to its RawByteString version as SearchRec is TRawByteSearchRec (fileutilh.inc)

This way {$mode delphiunicode} is completelly useless. I've tried to add FPC_UNICODE_RTL and FPC_OS_UNICODE to project defines. That does not help.

What is the correct way to use {$mode delphiunicode} to be compatible with Delphi source?

P.S. Lazarus 1.6.4 with FPC 3.0.2

Navigation

[0] Message Index

[#] Next page

Go to full version