[fpc-devel] QueryInterface on linux/i386 - adding 'in' parameter type?

Joost van der Sluis joost at cnoc.nl
Mon Aug 30 17:51:34 CEST 2010


On Sun, 2010-08-29 at 16:10 +0200, Michael Van Canneyt wrote:
> 
> On Sat, 28 Aug 2010, Joost van der Sluis wrote:
> 
> > Hi all,
> >
> > The safecall calling convention is now implemented for i386/linux in
> > fpc-trunk. The next step to get XPCom working now is to update the
> > QueryInterface (and AddRef and ReleaseRef) definitions in IInterface.
> >
> > Problem is that they are defined as 'stdcall' but to make them work on
> > Linux/i386 that should be 'cdecl'. So that will change in the near
> > future. (using an ifdef, so it's stdcall on windows, cdecl on all
> > others)
> > This will break backwards compatibility on non-windows systems for users
> > who implement their own QueryInterface, AddRef and ReleaseRef methods!
> > But it's easy fixable and the compiler will complain.
> >
> > The problem that then still remains is that the IID parameter of
> > QueryInterface has to be passed by reference. Now it's defined as
> > 'const' so it won't be passed by reference in Linux (cdecl).

I've read the other mails but respond to this one.

> What does stdcall calling convention currently do on non-windows platforms ?
> 
> Because if it is something we decided, it simply means that we should change
> it's meaning to be identical to mwpascal: cdecl calling convention, and const
> structs passed by reference. If I'm right, 'stdcall' currently
> has no meaning on non-windows platforms other than the one we put on it.

That was the first thing I though about, changing the meaning of stdcall
on non-windows platforms. But I find that kinda messy. Now 'stdcall' is
mainly defined as being callee-clean-up, parameters pushed
right-to-left. To make this dependent on the used OS is quite messy
imho.

Otoh, this is exactly what I did for 'safecall'. But 'safecall' is
slightly 'defined' as the COM/OLE-calling convention from Borland. Then
it is not that strange to make it XPCom compatible on non-Windows. (Even
if that changes the calling convention from callee-cleanup to
caller-cleanup)

Btw: I think I know why there are those differences between stdcall on
Windows and Linux that Jonas found. My guess is that Borland changed the
stdcall convention on some places to make live easier for them. (For
example: pass some records by value, because the WinApi demands that.)

> It solves all your problems in one go, plus it makes writing header
> translations a lot easier. (Pending the question of what the C compiler does
> with const structured C parameters)
> 
> If that is not possible, then I think Marco's idea of a switch is best.
> I see it as similar to the {$packrecords } directive: it doesn't change the
> syntax or meaning (as Jonas fears), but does instruct the compiler how to 
> handle things on a more low-level (in casu: assembler) scale.
> 
> I think that having to write
>    {$ifdef windows}const{$else}constref{$endif} myarg: mytype
> for possibly thousands of arguments in an interface description is simply not
> an option.

There is no need to add an {$ifdef windows} to the definition of
QueryInterface. Because on windows/stdcall record-parameters with a
size>pointersize are already passed by value. (Borland did this probably
just for this case) So when we use 'constref' effectively nothing
changes on Windows. 

The problem with the {$ifdef}'s does only exist for other header
conversions. (For example the Gecko headers) 

And Michael, this is all important for Gecko because all objects are
passed as interfaces. And Gecko uses QueryInterface to 'cast' one
interface to the other, so QueryInterface is called by Gecko a lot. Then
these calls have to be binary compatible. 

Changing the definition of QueryInterface to something completely
different is also hard, because now you can do:
  Object.QueryInterface(IInterface, AInterfaceInstance);
This is used a lot...

Conclusion(?)

I think that adding 'constref' is the best way to go. It's more
'pascalish', imho. And it has a clear meaning and use, namely converting
'typename const *' definitions from C-headers. 

If we want to have flexible ways of determine what to do exactly on a
function call, we have to design something different. (Which is maybe
not worth the trouble.)

Only disadvantage is that users have to add {$ifdef} statements if they
want to keep their header-files compilable on Delphi. In my opinion this
is a problem from Embarcadero. If we add new features to Pascal and they
don't, there's just nothing we can do about that. And not a reason to
come up with some syntax to avoid this incompatibility.

Did I now answer all questions to me?

Joost




More information about the fpc-devel mailing list