Jump to content
ChrisChuah

How to call functions with Interface name?

Recommended Posts

Hi

Currently, i am having problem with using Interfaces in Delphi 

 

I need to call this function

        function product_get_info(const info_type: IThriftHashSet<TProduct_info_type>): IProduct_info;

 

However, the parameters and return result are interfaces

 

====== Start IThriftHashSet ======

  // compatibility
  IHashSet<T> = interface( IThriftHashSet<T>)
    ['{C3CF557F-21D9-4524-B899-D3145B0389BB}']
  end deprecated 'use IThriftHashSet<T>';


  {$WARN SYMBOL_DEPRECATED OFF}
  TThriftHashSetImpl<T> = class( TInterfacedObject, IHashSet<T>, IThriftHashSet<T>, IThriftContainer, ISupportsToString)
  {$WARN SYMBOL_DEPRECATED DEFAULT}
  strict private
    FDictionary : TDictionary<T,Byte>;  // there is no THashSet<T> in older Delphi versions
  strict protected
    function GetEnumerator: TEnumerator<T>;
    function GetCount: Integer;
    property Count: Integer read GetCount;
    function Add( const item: T) : Boolean;
    procedure Clear;
    function Contains( const item: T): Boolean;
    function Remove( const item: T): Boolean;
  public
    constructor Create( const aCapacity: Integer = 0);  overload;
    constructor Create( const aCapacity: Integer; const aComparer : IEqualityComparer<T>);  overload;
    destructor Destroy; override;
    function ToString : string;  override;
  end;

===== End IThriftHashSet ====

 

=== Start IProduct_Info ====

  IProduct_info = interface(IBase)
    ['{F9E8E7FC-6023-48F0-940E-4B2EBC9A2258}']
    function GetTerminal_packaged_part_number_UTF8: System.UnicodeString;
    procedure SetTerminal_packaged_part_number_UTF8( const Value: System.UnicodeString);
    function GetTerminal_packaged_serial_number_UTF8: System.UnicodeString;
...

...

end;

 

  TProduct_infoImpl = class(TInterfacedObject, IBase, ISupportsToString, IProduct_info)
  private
    FTerminal_packaged_part_number_UTF8: System.UnicodeString;
    FTerminal_packaged_serial_number_UTF8: System.UnicodeString;
...

...

end

==== End IProduct_info ====

 

 

When i create a variable

hashset = TThriftHashSetImpl<TProduct_info_type>.create;

I could not call hashset.add(TProduct_info_type)

 

Also how do i handle the return result IProduct_info?

Should i also call 

product_info := TProduct_infoImpl.create??

 

Please help as i am not used to calling interfaces in Delphi

 

regards

chris

 

 

Share this post


Link to post
5 hours ago, ChrisChuah said:

When i create a variable

hashset = TThriftHashSetImpl<TProduct_info_type>.create;

I could not call hashset.add(TProduct_info_type)

It is expecting you to pass in an instance of the TProduct_info_type class, not the class itself.

5 hours ago, ChrisChuah said:

Also how do i handle the return result IProduct_info?

Should i also call 

product_info := TProduct_infoImpl.create??

No. product_get_info() will create the object for you and return an interface pointer to that object. You just need to declare a variable of type IProduct_info to receive it. 

Edited by Remy Lebeau

Share this post


Link to post

Hi Remy

 

the function 

        function product_get_info(const info_type: IThriftHashSet<TProduct_info_type>): IProduct_info;
 

requires a parameter which is an Interface of IThriftHashSet<TProduct_info_type>

 

  TProduct_info_type = (
    terminal_packaged_part_number = 0,
    terminal_packaged_serial_number = 1,
    terminal_packaged_comm_name = 2,
    sensor_packaged_part_number = 3,
    sensor_packaged_serial_number = 4,
    specific_part_number = 5,
    license_identifier = 6,
    license_name = 7,
    mac_address_ethernet = 8,
    mac_address_wifi = 9,
    mac_address_3g_modem = 10,
    RFID_board_type = 11,
    terminal_cie_part_number = 12,
    travel_totem_serial_number = 13,
    travel_totem_product_number = 14
  );

 

and this IThriftHashSet has a class like this

 

======== Start =======

  IThriftHashSet<T> = interface(IThriftContainer)
    ['{733E2B57-C374-4359-BBD5-2B9CD8DF737C}']
    function GetEnumerator: TEnumerator<T>;
    function GetCount: Integer;
    property Count: Integer read GetCount;
    function Add( const item: T) : Boolean;
    procedure Clear;
    function Contains( const item: T): Boolean;
    function Remove( const item: T): Boolean;
  end;

  // compatibility
  IHashSet<T> = interface( IThriftHashSet<T>)
    ['{C3CF557F-21D9-4524-B899-D3145B0389BB}']
  end deprecated 'use IThriftHashSet<T>';


  {$WARN SYMBOL_DEPRECATED OFF}
  TThriftHashSetImpl<T> = class( TInterfacedObject, IHashSet<T>, IThriftHashSet<T>, IThriftContainer, ISupportsToString)
  {$WARN SYMBOL_DEPRECATED DEFAULT}
  strict private
    FDictionary : TDictionary<T,Byte>;  // there is no THashSet<T> in older Delphi versions
  strict protected
    function GetEnumerator: TEnumerator<T>;
    function GetCount: Integer;
    property Count: Integer read GetCount;
    function Add( const item: T) : Boolean;
    procedure Clear;
    function Contains( const item: T): Boolean;
    function Remove( const item: T): Boolean;
  public
    constructor Create( const aCapacity: Integer = 0);  overload;
    constructor Create( const aCapacity: Integer; const aComparer : IEqualityComparer<T>);  overload;
    destructor Destroy; override;
    function ToString : string;  override;
  end;

====== End =====

 

 

How can i call this function product_get_info??

 

How to pass a IThriftHashSet into this function as parameter?

The only thing i can see is to use the TThriftHashSetImpl<T> constructor to create

After which, i cannot use the Add function as it is strict protected.

 

Is there a example or sample which i can read on how to pass interface as parameters to functions for Delphi?

 

please advise

 

regards

chris

 

 

 

Share this post


Link to post
14 minutes ago, ChrisChuah said:

the function 

        function product_get_info(const info_type: IThriftHashSet<TProduct_info_type>): IProduct_info;
 

requires a parameter which is an Interface of IThriftHashSet<TProduct_info_type>

That wasn't what was shown originally, but whatever.  My answer is the same.  You need to create an instance of a class that implements the IThriftHashSet interface, and then you can pass that instance into the function. For example:

var hashSet: IThriftHashSet<TProduct_info_type> := TThriftHashSetImpl<TProduct_info_type>.Create;
// or:
var hashSet := TThriftHashSetImpl<TProduct_info_type>.Create as IThriftHashSet<TProduct_info_type>;

hashSet.Add(terminal_packaged_part_number);
// etc ...

var info: IProduct_info := product_get_info(hashSet);
// or: var info := product_get_info(hashSet);
Quote

How to pass a IThriftHashSet into this function as parameter?

The only thing i can see is to use the TThriftHashSetImpl<T> constructor to create

Yes, exactly.  TThriftHashSetImpl implements IThriftHastSet, so that is the correct type to create an instance of.

Quote

After which, i cannot use the Add function as it is strict protected.

Yes, you can. Add() is public in the IThriftHashSet interface itself. It is protected only in the implementation of the interface.  You don't need access to the implementation, only to what the interface provides.  So, it is important that you call Add() on a variable whose type is IThriftHashSet not TThiftHashSetImpl.

Edited by Remy Lebeau

Share this post


Link to post

Hi Remy

I think i got it.

I need to create an instance of the TThriftHashSetImpl but the variable is an Interface itself

 

var

  hashset : IThriftHashSet<TProduct_info_type>;

  product_info : IProduct_info;

 

begin

  hashset := TThriftHashSetImpl<TProduct_info_type>.create;

  hashset.add(TProduct_Info_type.terminal_packaged_part_number);

  hashset.add(TProduct_info_type.terminal_packaged_serial_number);

  product_info := product_get_info(hashset);

end;

 

Another question:

How can i free or release these instances that i have created?

Wont there be any memory leak?

 

regards

chris

 

Share this post


Link to post
2 minutes ago, ChrisChuah said:

I think i got it.

I need to create an instance of the TThriftHashSetImpl but the variable is an Interface itself

Yes, exactly.

Quote

How can i free or release these instances that i have created?

Wont there be any memory leak?

By using variables of interface type, you don't need to free the instances yourself, as interfaces are reference-counted. There is no leak in your example.

Edited by Remy Lebeau

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×