[Lazarus] Making sources compatible with Delphi (but Lazarus is priority)

Sven Barth pascaldragon at googlemail.com
Mon May 1 19:36:22 CEST 2017


Am 01.05.2017 18:50 schrieb "Tony Whyman via Lazarus" <
lazarus at lists.lazarus-ide.org>:
>
>
>
> On 01/05/17 16:33, Sven Barth via Lazarus wrote:
>>
>> Would you please elaborate on these and which FPC version you targeted?
>>
>> Regards,
>> Sven
>>
>>
>>
> I am working with FPC 3.0.x and an example of the solution I used
follows. Note that with FPC, there is no problem calling a constructor from
a placeholder, while with delphi I found it necessary to add an explicit
coercion. I also wanted to return the interface provided by the object.
Again with FPC, this is easy. With Delphi, I found it necessary to use
QueryInterface to do the same.
>
> The difference between the two seems to be that FPC waits until the
generic is instantiated before type checking while Delphi performs type
checking when compiling the generic itself - or thereabouts. IMHO, FPC is
much superior to Delphi in this area.

Your assumption about the way FPC and Delphi do things is indeed correct.

Comments of mine follow inside your example.

> {$IFDEF FPC}
>   TOutputBlockItemGroup<_TItem,_IItem> = class(TOutputBlockItem)
> {$ELSE}
>   TOutputBlockItemGroup<_TItem: TOutputBlockItem; _IItem: IUnknown> =
class(TOutputBlockItem)
> {$ENDIF}

You should be able to use the second variant with FPC as well. It would
allow the compiler to do more type checking when parsing the generic
instead of when specializing it.

>   public
>     function GetItem(index: integer): _IItem;
>     function Find(ItemType: byte): _IItem;
>     property Items[index: integer]: _IItem read getItem; default;
>   end;
>
> ....
>
> {$IFDEF FPC}
> { TOutputBlockItemGroup }
>
> function TOutputBlockItemGroup<_TItem,_IItem>.GetItem(index: integer):
_IItem;
> var P: POutputBlockItemData;
> begin
>   P := inherited getItem(index);
>   Result := _TItem.Create(self.Owner,P);
> end;
>
> function TOutputBlockItemGroup<_TItem,_IItem>.Find(ItemType: byte):
_IItem;
> var P: POutputBlockItemData;
> begin
>   P := inherited Find(ItemType);
>   Result := _TItem.Create(self.Owner,P);
> end;
>
>
> {$ELSE}
>
> { TOutputBlockItemGroup }
>
> function TOutputBlockItemGroup<_TItem,_IItem>.GetItem(index: integer):
_IItem;
> var P: POutputBlockItemData;
>     Obj: TOutputBlockItem;
> begin
>   P := inherited getItem(index);
>   Obj := TOutputBlockItemClass(_TItem).Create(self.Owner,P);

Is this typecast really needed?

>   if Obj.QueryInterface(GetTypeData(TypeInfo(_IItem))^.Guid,Result) <> 0
then
>
IBError(ibxeInterfaceNotSupported,[GuidToString(GetTypeData(TypeInfo(_IItem))^.Guid)]);
> end;

"Result := Obj;" does not work? What about "Result := Obj as _IItem;"?

> function TOutputBlockItemGroup<_TItem,_IItem>.Find(ItemType: byte):
_IItem;
> var P: POutputBlockItemData;
>     Obj: TOutputBlockItem;
> begin
>   P := inherited Find(ItemType);
>   Obj := TOutputBlockItemClass(_TItem).Create(self.Owner,P);
>   if Obj.QueryInterface(GetTypeData(TypeInfo(_IItem))^.Guid,Result) <> 0
then
>
IBError(ibxeInterfaceNotSupported,[GuidToString(GetTypeData(TypeInfo(_IItem))^.Guid)]);
> end;

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20170501/586a9bea/attachment.html>


More information about the Lazarus mailing list