Talk:Implementing Interfaces: Delphi and C++

From RAD Studio
Jump to: navigation, search

Hello,

Starting with CBuilder 2011 you don't have to reimplement and forward the methods of IUnknown. Instead of deriving from TInterfacedObject, use the TCppInterfacedObject template: it handles IUnknown and you handle the method specific to your interface. Here's the example update to illustrate:


class TMyPersist: public TCppInterfacedObject<IPersist>
{
 HRESULT __stdcall GetClassID(CLSID *pClassID)
 {
   *pClassID = CLSID_SOMEVALUE;
   return S_OK;
 }
};


Response

I've incorporated your suggested addition.

Many thanks --

KrisHouser 15:46, 4 August 2010 (PDT)


Hello,

The new section added should go in the inheritance area as the template uses inheritance. I'll give you a new sample that illustrates the property implements soon.

Cheers,

Bruneau

Hello,

Here's a sample illustrating property implements in Delphi:


unit Unit1;

interface

type

  // Interface that exposes an 'Add' method
  IAdder = interface
  ['{D0C74612-9E4D-459A-9304-FACE27E3577D}']
    function Add(I, J: Integer): Integer;
  end;

  // Aggregatee that implements IAdder
  TAdder = class(TAggregatedObject, IAdder)
    function Add(I, J: Integer): Integer;
  end;

  // Aggregator - implements IAdder via TAdder
  TPasClass = class(TInterfacedObject, IAdder)
    FAdder: TAdder;
    function GetAdder: TAdder;
  public
    destructor Destroy; override;
    property Adder: TAdder read GetAdder write FAdder implements IAdder;
  end;

function TestAdd(I, J: Integer): Integer; 

implementation

{ TAdder }
function TAdder.Add(I, J: Integer): Integer;
begin
  Result := I+J;
end;

{ TPasClass }
destructor TPasClass.Destroy;
begin
  FAdder.Free;
  inherited;
end;

function TPasClass.GetAdder: TAdder;
begin
  if FAdder = nil then
    FAdder := TAdder.Create(Self as IInterface);
  Result := FAdder;
end;

// Adds using TClass' IAdder
function TestAdd(I, J: Integer): Integer; 
var
  punk: IInterface;
begin
  punk := TPasClass.Create as IInterface;
  Result := (punk as IAdder).Add(I, J);
end;

end.


And here's similar code for C++:



#include <System.hpp>
#include <stdio.h>

// Interface that exposes an Add(..) method
__interface  INTERFACE_UUID("{D0C74612-9E4D-459A-9304-FACE27E3577D}") IAdder  : public System::IInterface 
{
    virtual int __fastcall Add(int I, int J) = 0 ;
};
typedef System::DelphiInterface<IAdder> _di_IAdder;


// Aggregatee that implements IAdder
class TCppAdder: public TCppAggregatedObject<IAdder> {
public:
    __fastcall TCppAdder(const _di_IInterface Controller) : _AGGREGATED_CLASS(Controller)
    {}
    
    int __fastcall Add(int i, int j) 
    {
        return i+j;
    }
};


// Aggregator - exposes IAdder via TCppAdder
class TCppClass : public TInterfacedObject {
private:
    TCppAdder* obj; 
    IAdder* FAdder;
protected:
    void initAggregatee() 
    {
        _di_IInterface punk;
        GetInterface(punk);
        _di_IAdder adder;
        (obj = new TCppAdder(punk))->GetInterface(adder);
        FAdder = adder;
    }
public:
    __fastcall TCppClass()
    {
        initAggregatee();
    }
    __fastcall ~TCppClass()
    {
        delete obj;
    }
    __property IAdder* Adder = { read=FAdder, implements };
};

// Test: Invoke IAdder.Add(..) using TCppClass
int main()
{
    TCppClass* ptr; 
    _di_IAdder ia;
    if (!((ptr = new TCppClass())->GetInterface(ia)))
    {
        delete ptr;
    }
    else
    {
        int result = ia->Add(10, 20);
        printf("Add Result = %d\n", result);
    }
    return 0;
}