Sign in Join

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

Mailing lists / fpc-pascal / 2003-05

Interfaces, What am I doing wrong?

3 messages · 3 people ·

Reply by email Subscribe to this list Your subscription

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

Jon Sawyer

I'm trying to learn how to use Interfaces. I'm going by Delphi's documentation. I know that I'm ignoring GUIDs but as far as I can tell from the docs there not vital. If there are how can I generate my own?? ^_^ But I'm getting real stuck. The doc's on Delphi's web page mentions NOTHING about implementing IUnknown's methods. Do I have to?

Thanks for the help. ^_^

The code at the bottom generates the following compiler messages: ########## CONSOLE OUTPUT ############
bash-2.05b$ ppc386 qbase.pp
Free Pascal Compiler version 1.1 [2003/05/10] for i386 Copyright (c) 1993-2002 by Florian Klaempfl
Target OS: Linux for i386
Compiling qbase.pp
qbase.pp(14,7) Error: No matching implementation for interface method "IUnknown.QueryInterface(const TGuid,out <Formal type>):LongInt" found qbase.pp(14,7) Error: No matching implementation for interface method "IUnknown._AddRef:LongInt" found
qbase.pp(14,7) Error: No matching implementation for interface method "IUnknown._Release:LongInt" found
qbase.pp(28,1) Fatal: There were 3 errors compiling module, stopping bash-2.05b$
########### END OF CONSOLE OUTPUT ###########

########### SOURCE CODE #####################

{$Mode ObjFPC}
Unit QBase;
Interface
Type
  iQObject
    = Interface
        Procedure SetName(iName: String);
        Function  GetName: String;
        Property  Name   : String;
      end;
  tQObject
    = Class (iQObject)
      Protected
        fName       : String;
      Public
        Constructor Create;
        Destructor  Destroy; Override;
        Procedure   SetName(iName: String);
        Function    GetName: String;
        Property    Name   : String
          Read      GetName
          Write     SetName;
      end;
Implementation
Constructor tQObject.Create;
Begin
  fName := 'tQObject';
end;
Destructor  tQObject.Destroy;
Begin
end;
Procedure   tQObject.SetName(iName: String);
Begin
  Writeln('Renaming ', fName,' to ', iName);
  fName := iName;
end;
Function    tQObject.GetName: String;
Begin
  Result := fName;
end;
end.

Reply by email

Sebastian Günther
to Jon Sawyer
I'm trying to learn how to use Interfaces. I'm going by Delphi's documentation. I know that I'm ignoring GUIDs but as far as I can tell from the docs there not vital. If there are how can I generate my own?? ^_^

I think there is a GUID generator included with Microsofts Platform SDK

But I'm getting real stuck. The doc's on Delphi's web page mentions NOTHING about implementing IUnknown's methods. Do I have to?

Yes... The easiest way is to derive your implementation class from TInterfacedObject. If you cannot use TInterfacedObject: Just use the source of its implementation as a starting point for your code. AddRef and Release are very easy to implement; if you need QueryInterface, depends on your code. But it would be wise to implement QueryInterface as well (which requires the usage of IIDs, of course).

- Sebastian

Reply by email

Unknown author

I knocked up the following solution.

You do not need a GUID unless you want to use COM or a COM like interface. Borland have actually altered Interfaces in D6 onwards so that IUnknown inherits from IInterface and IInterface implements nothing at all (or very little anyway) to help facilitate the practice of Interfaces outside of COM.

NB. didn't actually compile this so it could fail. I think the uses clause is complete. Moved some of your fields/methods around for better encasulation.

Matt

////////////////////////////////////////////////////////////
unit QBase;
interface
{$MODE ObjFPC}
uses
  SySutils, Classes;
type
  IQObject = interface
    procedure SetName(iName: string); //these are annoying, but are needed
    function GetName: string;
    // iirc you need the full definition
    property Name: string read GetName write SetName;
  end;
  TQObject = class(TInterfacedObject, IQObject)
  private
    fName: string;
  protected
//interfaces don't care about scope so long as it's at least protected
//because private scop is invisible to descendents and this will break
//the interface I guess (though I've never tried this out)
    procedure SetName(iName: string); virtual;
    function GetName: string; virtual;
  public
    constructor Create;
    destructor Destroy; override;
    property Name: string read GetName write SetName;
  end;
//convenience routine
function NewQObjectIntf(AName: string = ''): IQObject;
implementation
function NewQObjectIntf(AName: string = ''): IQObject;
begin
  Result := TQObject.Create;
  if (AName  '') then
    Result.Name := AName;
end;
constructor tQOTQObjectbject.Create;
begin
  fName := 'TQObject';
end;
destructor TQObject.Destroy;
begin
  inherited; // << you NEEEEED this
end;
procedure TQObject.SetName(iName: string);
begin
  Writeln('Renaming ', fName, ' to ', iName);
  fName := iName;
end;
function TQObject.GetName: string;
begin
  Result := fName;
end;
end.

---------------------------------------------
This message was sent using Mistral WebMail.
http://www.mistral.co.uk/

Reply by email