Hello FPC-Pascal, Monday, June 7, 2010, 10:34:26 AM, you wrote:
JM> safecall is not supported (= ignored) on non-Windows platforms, JM> because it is completely Windows-specific. Afaik, GCC does not support JM> any safecall calling convention on Linux either. It is "silently" changed by stdcall do not ? >> Linux but mozilla's XPCOM and I think that finally GCC uses a hybird >> calling convention, it is the same as in Linux but the stack must be JM> That's actually the standard C calling convention, not a hybrid JM> calling convention (= cdecl, as you mention below). Yes, at the beginning it looks to me strange, because cdecl generates a totally different code (the TGUID problem) and my first idea was a non 100% standard calling convention, which is obviously wrong. >> So the same code to work in >> Linux (XPCOM) and in Windows: >> >> asm >> mov eax, [TheCOMInterface]; >> mov eax,[eax] >> push Intf; >> push IID; >> push ContractID; >> push TheCOMInterface; >> Call [eax]+16; >> {$IFDEF LINUX} >> add esp,16; >> {$ENDIF} >> call fpc_safecallcheck; >> end; JM> Are you certain when using XPCOM with GCC, it automatically transforms JM> every function so that First I must conclude that XPCOM in Linux is compiled with GCC and which version is being used, but I'm quite sure it is GCC ;) JM> a) the result is passed as a hidden parameter by reference JM> b) the actual function results becomes an error code Plain function result is in EAX, if I call (in ASM) QueryInterface with garbaged IIDs I get "$80004002" in the EAX (NOT_INTERFACE). Just the same as in Windows using safecall except the stack clean. JM> c) a check is inserted after every call that checks this error code To check this I must compile something with GCC and I do not have it installed and I do not have a source to compile with it. I should investigate following other paths. >> Could this be considered a bug in fpc interfaces ? JM> Yes, it is always wrong to assume that "const" enforces passing by JM> reference (except when using the mwpascal calling convention). So a "const x: TGUID" will be passed by reference in safecall and as 16 bytes in cdecl ? Is this OK ? Is this how GCC excepts a const parameter TGUID to be passed ? I'm asking because now I have changed my interface definition to use PGUID instead (both windows and linux) and it works more or less, but now I have a problem in the TInterfacedObject which seems to be the cause of some crashes, but I can not say by now if it is related to XPCOM exposing a different "IUnknown" (maybe cdecl instead stdcall) or TGUID related. I'll investigate further. One question, is there any way in fpc to "define" the calling convention as a C define ? Just something like: {$IFDEF UNIX} {$DEFINE THECALLING cdecl} {$ELSE} {$DEFINE THECALLING safecall} {$ENDIF} function x: integer; THECALLING; I had replaced all safecalls with: {$IFDEF xx}safecall{$ENDIF}{$IFDEF y}cdecl{$ENDIF} But it is quite "awful" :) -- Best regards, José _______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal