Delphi is heavily bound to Windows. Because of this, it introduced a lot of Windows-isms in the API (e.g. file searching and opening, loading libraries).
Free Pascal was designed to be portable, so things that are very Windows specific are missing, although the Free Pascal team tries to minimize this. The following are the main points that should be considered:
By default, Free Pascal generates console applications. This means that you must explicitly enable the GUI application type for Windows:
{$APPTYPE GUI}
The Windows unit provides access to most of the core Win32 API. Some calls may have different parameter lists: instead of declaring a parameter as passed by reference (var), a pointer is used (as in C). For most cases, Free Pascal provides overloaded versions of such calls.
Widestrings. Widestring management is not automatic in Free Pascal, since various platforms have different ways of dealing with widestring encodings and Multi-Byte Character Sets. FPC supports Widestrings, but may not use the same encoding as on Windows.
Note that in order to have correct widestring management, you need to include the cwstring unit on Unix/linux platforms: This unit initializes the widestring manager with the necessary callbacks which use the C library to implement all needed widestring functionality.
Threads: At this moment, Free Pascal does not offer native thread management on all platforms; on Unix, linking to the C library is needed to provide thread management in an FPC application. This means that a cthreads unit must be included to enable threads.
A much-quoted example is the SetLastOSError call. This is not supported, and will never be supported.
Filename Case sensitivity: Pascal is a case-insensitive language, so the uses clause should also be case insensitive. Free Pascal ensures case insensitive filenames by also searching for a lowercase version of the file. Kylix does not do this, so this could create problems if two differently cased versions of the same filename are in the path.
RTTI is NOT stored in the same way as for Delphi. The format is mostly compatible, but may differ. This should not be a problem if the API of the TypeInfo unit is used and no direct access to the RTTI information is attempted.
By default, sets are of different size than in Delphi, but set size can be specified using directives or command line switches.
Likewise, by default enumeration types are of different size than in Delphi. Here again, the size can be specified using directives or command line switches.
In general, one should not make assumptions about the internal structure of complex types such as records, objects, classes and their associated structure. For example, the VMT table layout is different, the alignment of fields in a record may be different, etc.
The same is true for basic types: on other processors the high and low bytes of a word or integer may not be at the same location as on an Intel processor (the endianness is different).
Names of local variables and method arguments are not allowed to match the name of a property or field of the class: this is bad practise, as there can be confusion as to which of the two is meant.