Marcos,
When I originally created the Firebird Pascal API package, I wrote it with FPC as the only intended target. However, I then got feedback asking for Delphi compatibility and I couldn't resist the challenge of seeing how easy it would be to convert the source code. In the end, it was not that difficult and the following summarises the changes needed (apart from the minor syntax changes):
1. Standard set of defines for all modules:
{$IFDEF MSWINDOWS}
{$DEFINE WINDOWS}
{$ENDIF}
{$IFDEF FPC}
{$mode delphi}
{$ENDIF}
The first one is needed to ensure that the "WINDOWS" defined symbol works with Delphi as well as FPC, while "mode delphi" is needed for FPC.
2. All strings declared explicitly as AnsiString expect where they are used with system calls (e.g. FileNames).
This rule may vary between applications. However, as FPC defaults to AnsiString and Delphi to WideString, it is usually a good idea to be explicit in your string types. In my case, most strings were the ASCII subset of UTF8 and AnsiString worked for me.
Similarly AnsiChar instead of Char.
3. PByte instead of PChar.
Most uses of PChar in FPC/Lazarus aren't to character strings but are instead used to point to untyped buffers. However, in Delphi, PChar now means widestring and you will be caught out if you try and use PChar for an untyped buffer. PByte has the same semantic in both FPC and Delphi and is a pointer to an unsigned byte.
4. PAnsiChar instead of PChar.
When PChar is used to genuinely point to a character string then as in point 2, you should be explicit about which type of string. PWideString may also be appropriate for some cases.
5. Take care when using string literals.
I added
{$IFDEF FPC}
{$codepage UTF8}
{$ENDIF}
to sources with string literals just to make sure that FPC interprets all strings as UTF8. However, you need to be careful with Delphi. In some of the test scripts I ended up with source code such as:
{$IFDEF DCC}
ByName('title').AsString := UTF8Encode('Blob Test ©€');
ByName('Notes').AsString := UTF8Encode('Écoute moi');
{$ELSE}
ByName('title').AsString := 'Blob Test ©€';
ByName('Notes').AsString := 'Écoute moi';
{$ENDIF}
The first case (DCC defined) is Delphi and as my strings were all UTF8, I added an explicit UTF8Encode to force the literal to UTF8 before assigning to the string. Note the above is a test case with literals chosen to show up differences between character sets.
6. Varargs
Delphi is much fussier than FPC about varargs constructs. If you have to use them then the only way this seems to work is e.g.
function blah(...): sometype; cdecl varargs;
7. Generics
If you don't have to go here then don't. Unfortunately I had dug a hole for myself and made extensive use of generics. Some of the differences are minor syntax, but others... Delphi and FPC just don't work the same way. Examples of problems are:
- calling a constructor from a function defined using generics.
- extracting an interface from an object defined using generics.
Both are possible, but with very different syntax.
8.TSystemCodePage does not exist in Delphi
You may need to add
{$IF not declared(TSystemCodePage)}
TSystemCodePage = word; {not defined in Delphi}
{$IFEND}
if you are using any Ansistring code page functions.
9. $IFEND or $ENDIF
As illustrated in point 8, older versions of Delphi demand $IFEND rather than $ENDIF to terminate conditional compilation.
I hope you find this a useful checklist.
Regards
Tony Whyman
MWA
Marcos Douglas B. Santos wrote 29 lines
It months ago I realized that Lazarus was saving the sources like that:
1- If there is only ANSI chars, save it as ANSI encode;
2. If there is more than ANSI chars, save it as UTF8 encode;
(correct me if I'm wrong about that)
I think this was changed when I updated my FPC to 3.* and Lazarus (trunk).
Everything continues works. This new behavior was completly
transparent to me... but I have a doubt:
If Delphi sources don't use UTF8, how is the best way to mantain
sources that need to work in both compilers?
I mean, I would like to work with FPC and Lazarus as I am used to
doing, without take concerns about "remember to change the encode of
these files", "remember to not put accented chars on code", or
something like that.
Is there some wiki page that explains this?
Are you working on projects that have these problems? Could you tell
me which is the best approach to deal with it?
Thank you.
Best regards,
Marcos Douglas
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20170501/5e52a5b2/attachment-0001.html>