Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2012-09

Using Macros for IInterface

18 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Graeme Geldenhuys

On 2012-09-25 22:16, Henry Vermaak wrote:> I've used a macro for this in the past. E.g. :

Show quoted text 9 lines
{$macro on} {$ifdef windows} {$define CCONV:=stdcall} {$else} {$define CCONV:=cdecl} {$endif} Then use CCONV where you would specify the calling convention.

Couldn't something like this be applied to IInterface too? So we can get rid of those horrible IFDEF lines. If you don't know what I am talking about, have a look at the IInterface definition.

        IUnknown = interface
          ['{00000000-0000-0000-C000-000000000046}']
          function QueryInterface({$IFDEF
FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) :
longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
          function _AddRef : longint;{$IFNDEF
WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
          function _Release : longint;{$IFNDEF
WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
        end;
        IInterface = IUnknown;

And all those IFDEF's must go in your own code too when you implement a class with IInterface support. Yuck!!

Cheers,
- Graeme -

Reply by email

Unknown author
to Graeme Geldenhuys
Graeme Geldenhuys wrote 33 lines
On 2012-09-25 22:16, Henry Vermaak wrote:> I've used a macro for this in the past. E.g. : > > {$macro on} > {$ifdef windows} > {$define CCONV:=stdcall} > {$else} > {$define CCONV:=cdecl} > {$endif} > > Then use CCONV where you would specify the calling convention. Couldn't something like this be applied to IInterface too? So we can get rid of those horrible IFDEF lines. If you don't know what I am talking about, have a look at the IInterface definition. IUnknown = interface ['{00000000-0000-0000-C000-000000000046}'] function QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; function _AddRef : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; function _Release : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; end; IInterface = IUnknown; And all those IFDEF's must go in your own code too when you implement a class with IInterface support. Yuck!!

Since years I am a proponent of a libcall calling convention which translates to the common library calling convention for the platform. i.e. stdcall on windows, cdecl on all other platforms. A much cleaner solution IMHO.

The FPC_HAS_CONSTREF should disappear as soon as the RTL must not be compilable with a previous version that does not have CONSTREF. (which in fact could be 2.6.0, but someone would have to confirm that)

Michael.

Reply by email

Sven Barth
to Graeme Geldenhuys: On 2012-09-25 22:16, Henry Vermaak wrote:> I've used a macro for this in the past. E.g. :
Graeme Geldenhuys wrote 29 lines
On 2012-09-25 22:16, Henry Vermaak wrote:> I've used a macro for this in the past. E.g. : > > {$macro on} > {$ifdef windows} > {$define CCONV:=stdcall} > {$else} > {$define CCONV:=cdecl} > {$endif} > > Then use CCONV where you would specify the calling convention. Couldn't something like this be applied to IInterface too? So we can get rid of those horrible IFDEF lines. If you don't know what I am talking about, have a look at the IInterface definition. IUnknown = interface ['{00000000-0000-0000-C000-000000000046}'] function QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; function _AddRef : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; function _Release : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; end; IInterface = IUnknown;

This depends on whether we want to enable $macro in the system unit... @core devs: does something speak agaist it?

And all those IFDEF's must go in your own code too when you implement a class with IInterface support. Yuck!!

In your own code you are free to use macros as you see it fit.

Also we should decide what we want to call these macros, so that IDEs and fpdoc can "workaround" them correctly.

My suggestions (if we do indeed enable it):
intfconst for constref/const
intfdecl for stdcall/cdecl {I would not use extdecl so that there are no potential conflicts}

Regards,
Sven

Reply by email

Sven Barth
to Unknown author: Since years I am a proponent of a libcall calling convention which translates to the…

Am 26.09.2012 12:23, schrieb

The FPC_HAS_CONSTREF should disappear as soon as the RTL must not be compilable with a previous version that does not have CONSTREF. (which in fact could be 2.6.0, but someone would have to confirm that)

You are right! I forgot about that. 2.6.0 already supports constref so we can indeed remove the FPC_HAS_CONSTREF part from trunk.

Regards,
Sven

Reply by email

Marco van de Voort
to Sven Barth: This depends on whether we want to enable $macro in the system unit... @core devs: does…

In our previous episode, Sven Barth said:

> end; > IInterface = IUnknown; This depends on whether we want to enable $macro in the system unit...

It doesn't work at all since macro's don't export over unit borders.

My suggestions (if we do indeed enable it): intfconst for constref/const intfdecl for stdcall/cdecl {I would not use extdecl so that there are no potential conflicts}

libcall was already mentioned. It also helps in a lot of other places, and kills ninetynine percent of macro use. (which IMHO is always a good thing)

Reply by email

Sven Barth
to Marco van de Voort
Marco van de Voort wrote 8 lines
In our previous episode, Sven Barth said: >> end; >> IInterface = IUnknown; > > This depends on whether we want to enable $macro in the system unit... It doesn't work at all since macro's don't export over unit borders.

Nowhere did I mention that it needs to be exported... that's why I thought of the following as a "convention".

Show quoted text 7 lines
> My suggestions (if we do indeed enable it): > intfconst for constref/const > intfdecl for stdcall/cdecl {I would not use extdecl so that there are no > potential conflicts} libcall was already mentioned. It also helps in a lot of other places, and kills ninetynine percent of macro use. (which IMHO is always a good thing)

The question is then whether this should indeed be a new calling convention or merely something that translates to stdcall/cdecl...

If that is decided it would be rather easy to implement and if it would be agreed I would implement it.

Regards,
Sven

Reply by email

Unknown author
to Sven Barth: Nowhere did I mention that it needs to be exported... that's why I thought of the…
Sven Barth wrote 23 lines
Am 26.09.2012 12:28, schrieb Marco van de Voort: > In our previous episode, Sven Barth said: >>> end; >>> IInterface = IUnknown; >> >> This depends on whether we want to enable $macro in the system unit... > > It doesn't work at all since macro's don't export over unit borders. > Nowhere did I mention that it needs to be exported... that's why I thought of the following as a "convention". >> My suggestions (if we do indeed enable it): >> intfconst for constref/const >> intfdecl for stdcall/cdecl {I would not use extdecl so that there are no >> potential conflicts} > > libcall was already mentioned. It also helps in a lot of other places, and > kills ninetynine percent of macro use. (which IMHO is always a good thing) The question is then whether this should indeed be a new calling convention or merely something that translates to stdcall/cdecl...

I would be in favour of handling it at the level of the parser, but simply translate to cdecl/stdcall.
I would not use a macro that is handled on the level of the scanner.

The parser has more info at it's disposal, which could be useful if the behaviour needs to be refined.

Michael.

Reply by email

Marco van de Voort
to Graeme Geldenhuys: Awesome! So I guess that could be back ported to 2.6.x (fixes branch) too - ready for…

In our previous episode, Graeme Geldenhuys said:

Show quoted text 5 lines
> You are right! I forgot about that. 2.6.0 already supports constref so > we can indeed remove the FPC_HAS_CONSTREF part from trunk. Awesome! So I guess that could be back ported to 2.6.x (fixes branch) too - ready for the possible 2.6.2 release some day?

I think you are misinterpreting something.

It means the interface will always be constref, and thus no ifdefing in FPC (if you don't support <2.6.0) will be necessary.

But users don't need to ifdef if they don't use compilers that don't support constref (FPC 2.4 series and delphi)

Reply by email

Graeme Geldenhuys
to Marco van de Voort
Marco van de Voort wrote
It means the interface will always be constref, and thus no ifdefing in FPC (if you don't support <2.6.0) will be necessary.

For fpGUI, I only support the latest stable release of FPC, so that would be 2.6.0. So I should be fine with removing that IFDEF then.

But users don't need to ifdef if they don't use compilers that don't support constref (FPC 2.4 series and delphi)

Umm, so here might be a problem. tiOPF is a shared code base between FPC and Delphi. Does the compiler mode (we use mode delphi in tiOPF) not affect the constref? After all, it seems Delphi doesn't have a constref correct? So in mode delphi the IInterface should always be defined in a Delphi compatible manner?

Or would this mean that in fpGUI my IInterface usage can always be constref - because fpGUI only supports FPC and only v2.6.0.

And in tiOPF the IInterface usage can always be const, because Delphi doesn't support constref, and we use mode delphi?

Regards,
- Graeme -

Reply by email

Marco van de Voort
to Graeme Geldenhuys

In our previous episode, Graeme Geldenhuys said:

Show quoted text 6 lines
> > It means the interface will always be constref, and thus no ifdefing in FPC > (if you don't support <2.6.0) will be necessary. For fpGUI, I only support the latest stable release of FPC, so that would be 2.6.0. So I should be fine with removing that IFDEF then.

Yes, but for that you don't depend on FPC to do or merge anything. The removing of the ifdef is only FPC internal cleanup.

Show quoted text 5 lines
> But users don't need to ifdef if they don't use compilers that > don't support constref (FPC 2.4 series and delphi) Umm, so here might be a problem. tiOPF is a shared code base between FPC and Delphi.

Yeah, why do you think I mentioned it? :-)

Does the compiler mode (we use mode delphi in tiOPF) not affect the constref?

Not that I know, or any other directive. IIRC it was argued that those methods were more implementation oriented (iow a bit internal), and that one ifdef doesn't matter much.

After all, it seems Delphi doesn't have a constref correct?

I don't know what XE3 improves in that regard. But since FPC encountered this problem only after going multiarchitecture, I don't expect Embarcadero to deal with that until the new Delphi compiler lands.

Or would this mean that in fpGUI my IInterface usage can always be constref - because fpGUI only supports FPC and only v2.6.0.

Yes.

And in tiOPF the IInterface usage can always be const, because Delphi doesn't support constref, and we use mode delphi?

No. There you will have to keep the ifdef till Embarcadero catches up.

Reply by email

Sven Barth
to Graeme Geldenhuys: For fpGUI, I only support the latest stable release of FPC, so that would be 2.6.0. So I…
Graeme Geldenhuys wrote 8 lines
On 2012-09-26 11:40, Marco van de Voort wrote: > > It means the interface will always be constref, and thus no ifdefing > in FPC > (if you don't support <2.6.0) will be necessary. For fpGUI, I only support the latest stable release of FPC, so that would be 2.6.0. So I should be fine with removing that IFDEF then.

Correct.

Show quoted text 15 lines
> But users don't need to ifdef if they don't use compilers that > don't support constref (FPC 2.4 series and delphi) Umm, so here might be a problem. tiOPF is a shared code base between FPC and Delphi. Does the compiler mode (we use mode delphi in tiOPF) not affect the constref? After all, it seems Delphi doesn't have a constref correct? So in mode delphi the IInterface should always be defined in a Delphi compatible manner? Or would this mean that in fpGUI my IInterface usage can always be constref - because fpGUI only supports FPC and only v2.6.0. And in tiOPF the IInterface usage can always be const, because Delphi doesn't support constref, and we use mode delphi?

A mode switch does not and can not affect how a method is declared especially if the method is already compiled. After all using "modeswitch unicodestring" in your own unit does not change what string type "TStrings" uses.

So: In fpGUI you can always use "constref" if you only support 2.6.0 and newer.

In tiOPF you'll have to live with IFDEFs, as Delphi doesn't support macros. You could try the following though (not tested at all):

=== source begin ===

{$ifdef fpc}
   {$macro on}
   {$define const:=constref}
   {$ifndef windows}
     {$define stdcall:=cdecl}
   {$endif}
{$endif}
   TSomeClass = class(TObject, IInterface)
     function QueryInterface(const iid : tguid;out obj) : longint; stdcall;
     // ...
   end;
{$ifdef fpc}
   {$macro off}
   // maybe add a "undefine const" and "undefine stdcall" just to be sure
{$endif}

=== source end ===

As I said: This is not tested and I'm not even sure it works, but it's worth a try.

Regards,
Sven

Reply by email

Sven Barth
to Marco van de Voort: In our previous episode, Graeme Geldenhuys said: Yes, but for that you don't depend on…
Marco van de Voort wrote 5 lines
> After all, it seems Delphi doesn't have a constref correct? I don't know what XE3 improves in that regard. But since FPC encountered this problem only after going multiarchitecture, I don't expect Embarcadero to deal with that until the new Delphi compiler lands.

The question is whether Embarcadero will deal with that at all as the concept of "constref" was only discussed and implemented after someone tried to use XPCOM...

Maybe someone should check how "const x: TGUID" behaves on other platforms supported by XE2 (Mac OS X, Win64)...

Regards,
Sven

Reply by email

Sven Barth
to Unknown author: I would be in favour of handling it at the level of the parser, but simply translate to…

Am 26.09.2012 12:37, schrieb

Show quoted text 20 lines
>>> My suggestions (if we do indeed enable it): >>> intfconst for constref/const >>> intfdecl for stdcall/cdecl {I would not use extdecl so that there >>> are no >>> potential conflicts} >> >> libcall was already mentioned. It also helps in a lot of other >> places, and >> kills ninetynine percent of macro use. (which IMHO is always a good >> thing) > > The question is then whether this should indeed be a new calling > convention or merely something that translates to stdcall/cdecl... I would be in favour of handling it at the level of the parser, but simply translate to cdecl/stdcall. I would not use a macro that is handled on the level of the scanner. The parser has more info at it's disposal, which could be useful if the behaviour needs to be refined.

Of course I would do it at the level of the parser. Otherwise we could just have used macros ;)

Regards,
Sven

Reply by email

Marco van de Voort
to Sven Barth: The question is whether Embarcadero will deal with that at all as the concept of…

In our previous episode, Sven Barth said:

Show quoted text 7 lines
> I don't know what XE3 improves in that regard. But since FPC encountered > this problem only after going multiarchitecture, I don't expect Embarcadero > to deal with that until the new Delphi compiler lands. The question is whether Embarcadero will deal with that at all as the concept of "constref" was only discussed and implemented after someone tried to use XPCOM...

The whole Embarcadero bit was a bit tongue-in-cheek. Nobody knows what E. will do. Specially now they seem to want to reinvent themselves into a 4GL like mobile platform

Reply by email

Florian Klämpfl
to Graeme Geldenhuys: For fpGUI, I only support the latest stable release of FPC, so that would be 2.6.0. So I…
Graeme Geldenhuys wrote 18 lines
On 2012-09-26 11:40, Marco van de Voort wrote: > > It means the interface will always be constref, and thus no ifdefing > in FPC > (if you don't support <2.6.0) will be necessary. For fpGUI, I only support the latest stable release of FPC, so that would be 2.6.0. So I should be fine with removing that IFDEF then. > But users don't need to ifdef if they don't use compilers that > don't support constref (FPC 2.4 series and delphi) Umm, so here might be a problem. tiOPF is a shared code base between FPC and Delphi. Does the compiler mode (we use mode delphi in tiOPF) not affect the constref? After all, it seems Delphi doesn't have a constref correct? So in mode delphi the IInterface should always be defined in a Delphi compatible manner?

You care about Delphi compatibility?

Reply by email

Graeme Geldenhuys
to Florian Klämpfl
Florian Klämpfl wrote
You care about Delphi compatibility?

:) I was waiting for that. I care about coding not having IFDEF yes - so it stays readable. tiOPF is the only project I work on that is a shared code base.

Graeme.

Reply by email