Andreas K. Foerster wrote:
First of all, the types for variables are very different. SDL4fp uses "LongInt" for what is "int" in C - because LongInt happens to be 32Bit wide in FPC. But in GPC a LongInt is "at least" :-) 64bit wide! So it doesn't fit.
Older versions of GPC intentionally kept the variable types compatible to their counterparts in C. Newer versions broke with that and introduced speacial types, like CInteger or CLongInt.
Only CInteger (and its unsigned variants), there's no CLongInt.
(Background: Originally, some 10 years ago, we decided to match GPC's "Integer" to C's "int", for "natural" header conversion, expecting that "int" in C would follow the word size, so just as it changed from 16 bit on 16 bit targets to 32 bit on most 32 bit targets, it would change to 64 bit on 64 bit targets. Later, seeing that this didn't happen, instead C seems to fix "int" at 32 and requiring "long" for 64 bit types on most 64 bit targets, and given that "Integer" has a special status in Pascal, as it's the only predefined integer type in standard Pascal, and the base type of integer subranges, and thus the type in which arithmetic operations are performed etc., we followed a suggestion by Scott Moore, to increase "Integer" to 64 bit on 64 bit targets, which prompted the addition of a new type, "CInteger", which always matches C's "int". We did the same for unsigned types, even though "Cardinal" and "Word" are not in standard Pascal. For other types, C compatibility rules haven't changed, e.g. "MedInt" is and was compatible to C's "long int".)
Note that you have to change "LongInt" to "CInteger" and "PChar" to "CString" in SDL4fp.
BTW, GPC support both "PChar" and "CString" built-in. However, indeed I prefer to write "CString" when I mean a pointer to a "C string" (i.e., Chr(0)-terminated array of chars), instead of a pointer to a single character (which "PChar" is according to a common way of notation).
SDL4fp links to the library by using the name 'SDL' after the "external" modifier. This doesn't work in GPC (yet). In GPC you have to use the compiler directive "{$L SDL}". In FPC there's also a possability to use it in a similar way with "{$LinkLib SDL}"... well it works, but not in every situation. So I decided to keep the name after the external clause, but with "IfDef"s around it. GPC compiles it without the IfDef, but there are lot of warning messages then.
One way to avoid the ifdefs might be a macro that expands to "external 'SDL'" in FPC, and just "external" in GPC (and perhaps taking care of the "cdecl" as well for FPC, to further save typing).
C is case sensitive, while Pascal is not. So in GPC all Pascal identifiers are converted to lowercase at an early stage, this includes the procedure names. So you have a problem when your C identifiers need uppercase letters. This can only be solved by using an attribute which mentions the name again with its capitalisation: "name 'Example'".
Even when they don't need any uppercase letters, it's recommended to always specify the linker name for external declarations.
Well I still have a problem with CString parameters. FPC needs a type cast, while GPC doesn't accept a type cast here. I "solved" it again with "IfDef"s. Does anybody know a better solution?
Perhaps another macro (just a quick idea, as I actually don't like macros too much), that does a type-cast in FPC and nothing in GPC. (Perhaps it could even be a type equal to CString in FPC, though with another name, working as a type-cast by itself, and a nop-macro in GPC.)
Frank