Re: [fpc-pascal] Interface performance

2016-11-12 Thread Ryan Joseph

> On Nov 12, 2016, at 3:29 PM, Sven Barth  wrote:
> Avoid this casting by storing the interface reference. Will make your life 
> much easier and your code more maintainable.

Yes storing the interface works and seems to be the best solution for now. I 
did learn that generics could clean up the problem further but I need to adapt 
more code to make that work easily and removing the constant Support calls is 
good enough to put my mind at ease. :)

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Interface performance

2016-11-12 Thread Andrew Haines

On 11/11/2016 10:14 PM, Ryan Joseph wrote:

Arr := TArray.Create;
Obj := ObjInt.GetObject;
Arr.AddObject(Obj);

[do some stuff]

// here the problems start because TArray always returns TObject
// and I can’t cast TObject to IMyInterface even though the object
// stored in the array does in fact implement IMyInterface

ObjInt := IMyInterface(Arr.GetObject(0)); // error! but I need to get a 
reference to IMyInterface from the array

// I have to use “as” or Supports here and it defeats the purpose
ObjInt := Arr.GetObject(0) as IMyInterface;


 You have two options if you have a list of TObject.

1.  (Arr.GetObject(n) as IMyInterface).DoSomething;

2.  TMyObjectClass(Arr.GetObject(n)).DoSomething;

2 is kind of pointless because the interface is not being used so why 
have it.


Probably it is better to keep a list of IMyInterface rather than TObject.


I made a small test and uploaded it to github if you want to check it 
out. It uses a list of IMyInterface.


https://github.com/andrewd207/interfacetest

Or as a zip:

https://github.com/andrewd207/interfacetest/archive/master.zip


Regards,

Andrew Haines
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-12 Thread Sven Barth
Am 12.11.2016 04:46 schrieb "Ryan Joseph" :
>
>
> > On Nov 12, 2016, at 3:22 AM, Jonas Maebe 
wrote:
> >
> > You're passing a class, not an object. Passing a class that implements
an interface to a method that expects that interface should work fine.
Converting a class instance to an interface that it implements is trivial
and always works, it's doing the opposite that is hard and that requires
specific support in the interface.
>
> Here’s a better example of where this breaks. Yes casting does work to an
extent but breaks eventually down the chain when I lose the reference. Is
there anyway to get around this? Maybe I could store the reference from
Supports inside TMyObjectClass so I don’t need to call Supports again?
>
> type
> IMyInterface = interface
>   procedure DoSomething;
> function GetObject: TObject;
>  end;
>
> type
> TMyObjectClass = class(IMyInterface)
> procedure DoSomething;
> function GetObject: TObject;
> end;
>
> var Obj: TMyObjectClass
> ObjInt: IMyInterface;
>
> Obj := TMyObject.Create;
> ObjInt := Obj; // this works fine, casting to an interface
>
> // Unit A only knows about IMyInterface so we pass
> // the class cast as an interface (not sure what to call this)
> DomeSomethingInUnitA(ObjInt);
>
> // Unit A
> var Obj: TObject;
> Arr: TArray; // collection class the stores TObject
>
> Arr := TArray.Create;
> Obj := ObjInt.GetObject;
> Arr.AddObject(Obj);

*Here* is your problem. You should use a container class that handles your
interface type to store your interface reference. Especially generics come
to mind here (e.g. fgl's TFPGList<> or Generics.Containers' TList<>).
Also it's a bad design that you work with an interface and then assume that
it's baked by a TObject instance. E.g. with a COM interface it might come
from some C++ code. Then what?

> [do some stuff]
>
> // here the problems start because TArray always returns TObject
> // and I can’t cast TObject to IMyInterface even though the object
> // stored in the array does in fact implement IMyInterface
>
> ObjInt := IMyInterface(Arr.GetObject(0)); // error! but I need to get a
reference to IMyInterface from the array
>
> // I have to use “as” or Supports here and it defeats the purpose
> ObjInt := Arr.GetObject(0) as IMyInterface;

Avoid this casting by storing the interface reference. Will make your life
much easier and your code more maintainable.

Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-11 Thread Ryan Joseph

> On Nov 12, 2016, at 3:22 AM, Jonas Maebe  wrote:
> 
> You're passing a class, not an object. Passing a class that implements an 
> interface to a method that expects that interface should work fine. 
> Converting a class instance to an interface that it implements is trivial and 
> always works, it's doing the opposite that is hard and that requires specific 
> support in the interface.

Here’s a better example of where this breaks. Yes casting does work to an 
extent but breaks eventually down the chain when I lose the reference. Is there 
anyway to get around this? Maybe I could store the reference from Supports 
inside TMyObjectClass so I don’t need to call Supports again?

type
IMyInterface = interface
  procedure DoSomething; 
function GetObject: TObject;
 end;  

type
TMyObjectClass = class(IMyInterface)
procedure DoSomething;
function GetObject: TObject;
end; 

var Obj: TMyObjectClass
ObjInt: IMyInterface;

Obj := TMyObject.Create;
ObjInt := Obj; // this works fine, casting to an interface

// Unit A only knows about IMyInterface so we pass
// the class cast as an interface (not sure what to call this)
DomeSomethingInUnitA(ObjInt);

// Unit A
var Obj: TObject;
Arr: TArray; // collection class the stores TObject

Arr := TArray.Create;
Obj := ObjInt.GetObject;
Arr.AddObject(Obj);

[do some stuff]

// here the problems start because TArray always returns TObject
// and I can’t cast TObject to IMyInterface even though the object
// stored in the array does in fact implement IMyInterface

ObjInt := IMyInterface(Arr.GetObject(0)); // error! but I need to get a 
reference to IMyInterface from the array

// I have to use “as” or Supports here and it defeats the purpose
ObjInt := Arr.GetObject(0) as IMyInterface;


Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-11 Thread Jonas Maebe

On 11/11/16 16:28, Ryan Joseph wrote:

On Nov 11, 2016, at 8:54 PM, Tony Whyman  wrote:

If you go back to the FPC documentation, in the User Guide it says "Objects are 
stored in memory just as ordinary records with an extra field: a pointer to the Virtual 
Method Table (VMT)."


That text is about Turbo Pascal-style objects, not about classes.


My understanding is that an interface is stored similarly, except that a 
different VMT is used i.e. that which defines the interface. If you try and 
assign one to the other by just coercing the type then you will get undefined 
results.

I think what I’m trying to do is just not compatible with how interfaces work 
in FPC then. I’m trying to pass an object (which implements an interface) and 
then without using “as” or Supports access the interface for that object so I 
can call its methods. I keep running into crashes and from your description 
it’s because I only have an object but I need the interface reference which 
MUST use a string lookup. Casting an object as its interface causes undefined 
results.


You're passing a class, not an object. Passing a class that implements 
an interface to a method that expects that interface should work fine. 
Converting a class instance to an interface that it implements is 
trivial and always works, it's doing the opposite that is hard and that 
requires specific support in the interface.



Jonas
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-11 Thread Ryan Joseph

> On Nov 11, 2016, at 8:54 PM, Tony Whyman  
> wrote:
> 
> If you go back to the FPC documentation, in the User Guide it says "Objects 
> are stored in memory just as ordinary records with an extra field: a pointer 
> to the Virtual Method Table (VMT)." My understanding is that an interface is 
> stored similarly, except that a different VMT is used i.e. that which defines 
> the interface. If you try and assign one to the other by just coercing the 
> type then you will get undefined results.

I think what I’m trying to do is just not compatible with how interfaces work 
in FPC then. I’m trying to pass an object (which implements an interface) and 
then without using “as” or Supports access the interface for that object so I 
can call its methods. I keep running into crashes and from your description 
it’s because I only have an object but I need the interface reference which 
MUST use a string lookup. Casting an object as its interface causes undefined 
results.

It seems trivial to be avoiding a string lookup but in some tight loops and 
sorting functions the call to Supports is taking far more time than the actual 
sorting so it’s clearly not a good solution.

More on this tomorrow until I give up for certain. :)

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-11 Thread Sven Barth
Am 11.11.2016 15:16 schrieb "Graeme Geldenhuys" <
mailingli...@geldenhuys.co.uk>:
>
> On 2016-11-11 10:52, Tony Whyman wrote:
> > Someone else may correct me, but with CORBA, I believe you have to
> > explicitly add a function to the interface such as
> >
> > function GetObject: TMyObject;
>
>
> I may be wrong too, but I thought, for reliable results, you had to do
> that for COM and CORBA style interfaces. Then again, I've used
> Interfaces for 15+ years and once I have a interface reference, I never
> needed to get back to the originating object. Maybe I was just lucky in
> my use cases. ;-)

For COM interfaces there is support for the as-operator as every TObject
has an implicit self reference interface that's returned by
QueryInterface(). The raw CORBA interfaces (or internally called raw
interfaces) don't have such a method thus no such as-operator.

Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-11 Thread Graeme Geldenhuys
On 2016-11-11 10:52, Tony Whyman wrote:
> Someone else may correct me, but with CORBA, I believe you have to 
> explicitly add a function to the interface such as
> 
> function GetObject: TMyObject;


I may be wrong too, but I thought, for reliable results, you had to do
that for COM and CORBA style interfaces. Then again, I've used
Interfaces for 15+ years and once I have a interface reference, I never
needed to get back to the originating object. Maybe I was just lucky in
my use cases. ;-)

Regards,
  Graeme

-- 
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

My public PGP key:  http://tinyurl.com/graeme-pgp
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Interface performance

2016-11-11 Thread Tony Whyman

  Isn’t MyObject2 still pointing to MyObject1?
If you go back to the FPC documentation, in the User Guide it says 
"Objects are stored in memory just as ordinary records with an extra 
field: a pointer to the Virtual Method Table (VMT)." My understanding is 
that an interface is stored similarly, except that a different VMT is 
used i.e. that which defines the interface. If you try and assign one to 
the other by just coercing the type then you will get undefined results.



On 11/11/16 11:25, Ryan Joseph wrote:

On Nov 11, 2016, at 5:52 PM, Tony Whyman  wrote:

Someone else may correct me, but with CORBA, I believe you have to explicitly 
add a function to the interface such as

function GetObject: TMyObject;

and implement as

function TMyObject.GetObject: TMyObject;
begin
  Result := self;
end;

I think I’m out of time now but I’ll try this in my code that was crashing 
before.

How is this different from just casting the interface to an object? There’s 
your example below basically like I was doing it before with the seemingly 
random crashes. Isn’t MyObject2 still pointing to MyObject1?

type
IMyInterface = interface
procedure MyProc;
end;

TMyObjectClass = class(TInterfacedObject,IMyInterface)
public
   procedure MyProc;
end;

var MyObject1, MyObject2: TMyObjectClass;
  MyInterface: IMyInterface;

begin
  MyObject1 := TMyObjectClass.Create;
  MyInterface := MyObject1;

  MyInterface.MyProc;

  MyObject2 := TMyObjectClass(MyInterface);

  MyObject1.Free {OK for CORBA - will cause an exception in COM}
  {MyObject1, MyObject2 and MyInterface are now all invalid}
end;


Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal



___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-11 Thread Martin Schreiber
On Friday 11 November 2016 12:08:26 Graeme Geldenhuys wrote:
> On 2016-11-11 09:46, Ryan Joseph wrote:
> > The string lookup absolutely murders performance (I was using “cobra”
> > interfaces) so it can’t be used in some situations.
>
> If you are talking about the GUID, I'm not sure if you know, but when
> using FPC's CORBA interfaces, you can use a MUCH shorter string which
> gives better performance. MSEide even has built-in support to do just
> that (generate smaller GUID values of about 6 characters long).
>
The minimum are 2 characters. Seeing that, actually the minimum could be 1, 
there is room for improvement. ;-)
GUID is a little bit excessive, I call them UID.

Martin
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-11 Thread Tony Whyman

On 11/11/16 10:59, Ryan Joseph wrote:

What does memory management even mean for interfaces? I never allocate an 
interface I just implement it in a class so what’s there to be freed? All these 
crashes I’m getting suggest memory is being trashed by the compiler at some 
point without my knowledge. I never explicitly allocate an interface like an 
object so there’s nothing to manage in my mind.
May be that the best way to understand an interface is to think of it as 
a pointer to a class's VMT (or at least a VMT derived from the class's 
VMT) plus a reference to the object 'self'). When you call a method that 
belongs to an interface, the underlying code simply performs a VMT 
lookup and calls the method at the selected table location and provides 
the 'self' reference to the method. The result is then no different to a 
normal method call.


Interfaces do exist independent of objects. They depend on underlying 
object instances for their implementation.


An interface continues to work as long as the 'self' reference is valid. 
Once the underlying object is freed then the 'self'' reference becomes 
invalid and the interface no longer works.


With CORBA, you are responsible for creating and freeing the object 
instances providing an interface. Under COM, you are still responsible 
for creating the objects. They are automatically freed when the 
interface (and any copies) go out of scope.

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-11 Thread Ryan Joseph

> On Nov 11, 2016, at 5:52 PM, Tony Whyman  
> wrote:
> 
> Someone else may correct me, but with CORBA, I believe you have to explicitly 
> add a function to the interface such as
> 
> function GetObject: TMyObject;
> 
> and implement as
> 
> function TMyObject.GetObject: TMyObject;
> begin
>  Result := self;
> end;

I think I’m out of time now but I’ll try this in my code that was crashing 
before.

How is this different from just casting the interface to an object? There’s 
your example below basically like I was doing it before with the seemingly 
random crashes. Isn’t MyObject2 still pointing to MyObject1?

type
IMyInterface = interface
   procedure MyProc;
end;

TMyObjectClass = class(TInterfacedObject,IMyInterface)
public
  procedure MyProc;
end;

var MyObject1, MyObject2: TMyObjectClass;
 MyInterface: IMyInterface;

begin
 MyObject1 := TMyObjectClass.Create;
 MyInterface := MyObject1;

 MyInterface.MyProc;

 MyObject2 := TMyObjectClass(MyInterface);

 MyObject1.Free {OK for CORBA - will cause an exception in COM}
 {MyObject1, MyObject2 and MyInterface are now all invalid}
end;


Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-11 Thread Ryan Joseph

> On Nov 11, 2016, at 5:44 PM, Tony Whyman  
> wrote:
> 
> With CORBA you are responsible for freeing the objects that provide an 
> interface in the same way that you are always responsible for freeing the 
> objects that you create. If you free an object before you finish using it 
> then it's a bug and using interfaces does not change that.

I’m happy to use CORBA but that means I can’t cast an interface back to an 
object using “as” but I’m not sure that’s the reason I was getting that crash 
(I need to make a test example I guess) but you seem to think “as” is needed 
but CORBA doesn’t allow this.

Tried to switch  CORBA interface to a COM now and got another strange crash 
accessing memory.

What does memory management even mean for interfaces? I never allocate an 
interface I just implement it in a class so what’s there to be freed? All these 
crashes I’m getting suggest memory is being trashed by the compiler at some 
point without my knowledge. I never explicitly allocate an interface like an 
object so there’s nothing to manage in my mind.

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-11 Thread Ryan Joseph

> On Nov 11, 2016, at 6:08 PM, Graeme Geldenhuys 
>  wrote:
> 
> If you are talking about the GUID, I'm not sure if you know, but when
> using FPC's CORBA interfaces, you can use a MUCH shorter string which
> gives better performance. MSEide even has built-in support to do just
> that (generate smaller GUID values of about 6 characters long).

I’m not sure all Supports does but I didn’t test shorter strings yet. I think 
it does more than just compare strings though. Maybe I’ll try that later thanks.


Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-11 Thread Graeme Geldenhuys
On 2016-11-11 09:46, Ryan Joseph wrote:
> The string lookup absolutely murders performance (I was using “cobra”
> interfaces) so it can’t be used in some situations.

If you are talking about the GUID, I'm not sure if you know, but when
using FPC's CORBA interfaces, you can use a MUCH shorter string which
gives better performance. MSEide even has built-in support to do just
that (generate smaller GUID values of about 6 characters long).

Regards,
  Graeme

-- 
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

My public PGP key:  http://tinyurl.com/graeme-pgp
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-11 Thread Tony Whyman

On 11/11/16 10:08, Ryan Joseph wrote:

I’m trying your code example now and I get "Class or COM interface type 
expected, but got “IMyInterface”” when I try to cast with “as”. I was using 
{$interfaces corba} so maybe that’s the problem?

Ooops, as you may guess, I typically work with COM interfaces.

Someone else may correct me, but with CORBA, I believe you have to 
explicitly add a function to the interface such as


function GetObject: TMyObject;

and implement as

function TMyObject.GetObject: TMyObject;
begin
  Result := self;
end;

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-11 Thread Tony Whyman

On 11/11/16 10:25, Ryan Joseph wrote:

On Nov 11, 2016, at 4:56 PM, Tony Whyman  wrote:

3. To get an object back from an interface you must use the "as" operator.

Another point to do with CORBA. The manual says they are not reference counted 
and programmer needs to do book keeping. The crash I was getting was in line 
with accessing memory that has been deallocated so perhaps because I didn’t do 
my “book keeping” it was freed as it passed scopes. Not sure how to manage 
reference counting for interfaces though because the docs didn’t actually 
explain this.

Maybe the better question is should I ditch CORBA in favor or COM?


Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


If last question doesn't send the list into overdrive then nothing will;)

With CORBA you are responsible for freeing the objects that provide an 
interface in the same way that you are always responsible for freeing 
the objects that you create. If you free an object before you finish 
using it then it's a bug and using interfaces does not change that.


With COM, once you assign the object providing the interface to a 
variable with an interface type then you are no longer responsible for 
freeing the object. The object is now managed by the system and if you 
do free it then you get an exception. It's really the same principle as 
AnsiStrings and dynamic arrays, which are also reference counted objects.


The classic newbie problem with COM comes when you have an interface 
with a method that returns another interface. If the underlying objects 
"know" about each other and reference each other's data then the order 
in which they are freed becomes important and automatic reference 
counting does not always give the right answer. There are design 
techniques to manage this, such as objects keeping interface references 
to other objects - but then you have to be careful to avoid circular 
references that prevent the objects ever being released.


I would start working with interfaces by using CORBA. It's more obvious 
what is going on and fewer traps for the unwary. However, if you are 
designing a standard package providing an API realised as a Pascal 
Interface then I would argue that a properly designed COM based 
interface is easier for the API user, in the same way that AnsiStrings 
just "work".

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-11 Thread Ryan Joseph

> On Nov 11, 2016, at 4:56 PM, Tony Whyman  
> wrote:
> 
> 3. To get an object back from an interface you must use the "as" operator.

This step I was not doing and the “as” operator from an earlier showed it uses 
a string lookup anyways so it defeated the purpose in some cases (but better 
than my previous solution using Supports for all access).

I’m trying your code example now and I get "Class or COM interface type 
expected, but got “IMyInterface”” when I try to cast with “as”. I was using 
{$interfaces corba} so maybe that’s the problem?



Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-11 Thread Ryan Joseph

> On Nov 11, 2016, at 4:56 PM, Tony Whyman  
> wrote:
> 
> 3. To get an object back from an interface you must use the "as" operator.

Another point to do with CORBA. The manual says they are not reference counted 
and programmer needs to do book keeping. The crash I was getting was in line 
with accessing memory that has been deallocated so perhaps because I didn’t do 
my “book keeping” it was freed as it passed scopes. Not sure how to manage 
reference counting for interfaces though because the docs didn’t actually 
explain this.

Maybe the better question is should I ditch CORBA in favor or COM?


Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-11 Thread Tony Whyman

On 11/11/16 09:46, Ryan Joseph wrote:

I just don’t plain get it. The examples given seem to be a redundant property 
that could be replaced with a reference the interface itself.
Interface delegation is really just an optimisation and is equivalent to 
defining a set of methods to support the interface and each one then 
calls the same method in the "delegated" interface. IMHO, extending the 
definition of a property for this optimisation isn't exactly intuitive.


Delegated interfaces cause even more problems with reference counted COM 
interfaces. Unless you are really confident in your use of interfaces - 
just don't go there.

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-11 Thread Tony Whyman

On 11/11/16 09:46, Ryan Joseph wrote:

Just as I got this message I’m running into some inexplicable memory related 
crashes casting from interfaces to objects and calling methods.  Are you sure 
you can just cast these around like that? The compiler seems to get confused 
and lose track of what the type actually is. In my first test this didn’t 
happen and I was able to use an interface as a type then cast it to an object, 
pass to a function and call a method. In the 2nd example the variable went from 
a couple classes first and died at the end. Seems very unstable.
You will probably need to post some examples to get more help. But here 
are some simple rules:


1. Classes that provide interfaces in most cases will have 
TInterfacedObject as their ancestor.


2. If you have an object with a class definition that explicitly 
supports a given interface then to get an interface reference all you 
need to do is to assign it to a variable of the interface type.


3. To get an object back from an interface you must use the "as" operator.

e.g.

type
 IMyInterface = interface
procedure MyProc;
 end;

 TMyObjectClass = class(TInterfacedObject,IMyInterface)
 public
   procedure MyProc;
 end;

var MyObject1, MyObject2: TMyObjectClass;
  MyInterface: IMyInterface;

begin
  MyObject1 := TMyObjectClass.Create;
  MyInterface := MyObject1;

  MyInterface.MyProc;

  MyObject2 := MyInterface as TMyObjectClass;

  MyObject1.Free {OK for CORBA - will cause an exception in COM}
  {MyObject1, MyObject2 and MyInterface are now all invalid}
end;
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-11 Thread Ryan Joseph

> On Nov 11, 2016, at 4:31 PM, Tony Whyman  
> wrote:
> 
> You'll find a couple threads earlier this year in heated debate about 
> interface delegation and how it is implemented. My conclusion was to avoid 
> interface delegation - there are just too many traps for the unwary.

I just don’t plain get it. The examples given seem to be a redundant property 
that could be replaced with a reference the interface itself.

> 
> There is also another thread bemoaning some odd features about the "supports" 
> function.

The string lookup absolutely murders performance (I was using “cobra” 
interfaces) so it can’t be used in some situations.

> 
> In use, once you have a variable containing a reference to an interface, it 
> behaves, for the most part, the same as a reference to an object supporting 
> the same methods and properties and should be used as such.

Just as I got this message I’m running into some inexplicable memory related 
crashes casting from interfaces to objects and calling methods.  Are you sure 
you can just cast these around like that? The compiler seems to get confused 
and lose track of what the type actually is. In my first test this didn’t 
happen and I was able to use an interface as a type then cast it to an object, 
pass to a function and call a method. In the 2nd example the variable went from 
a couple classes first and died at the end. Seems very unstable.

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-11 Thread Tony Whyman

Ryan,

You'll find a couple threads earlier this year in heated debate about 
interface delegation and how it is implemented. My conclusion was to 
avoid interface delegation - there are just too many traps for the unwary.


There is also another thread bemoaning some odd features about the 
"supports" function.


In use, once you have a variable containing a reference to an interface, 
it behaves, for the most part, the same as a reference to an object 
supporting the same methods and properties and should be used as such.


Tony Whyman

MWA


On 11/11/16 08:25, Ryan Joseph wrote:

I did some experimenting this morning and found out I could pass references to 
the interface and call methods directly without using Supports and incurring 
the string compare penalty. There’s also interface delegation I read about and 
using “implements” keyword but I couldn’t understand what the purpose of this 
is and why it’s even useful.


On Nov 10, 2016, at 6:45 PM, Ryan Joseph  wrote:

Some times when I want to communicate with a class I don’t have full scope 
access to I’ll use interfaces and the Supports function to call a method. I’ve 
noticed however that the string compare function that it is used to find the 
interface in the class is very slow and makes them not useable for high 
performance situations. Is there a better way to do this or should I not use 
interfaces like this in FPC?

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal



___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-11 Thread Ryan Joseph
I did some experimenting this morning and found out I could pass references to 
the interface and call methods directly without using Supports and incurring 
the string compare penalty. There’s also interface delegation I read about and 
using “implements” keyword but I couldn’t understand what the purpose of this 
is and why it’s even useful.

> On Nov 10, 2016, at 6:45 PM, Ryan Joseph  wrote:
> 
> Some times when I want to communicate with a class I don’t have full scope 
> access to I’ll use interfaces and the Supports function to call a method. 
> I’ve noticed however that the string compare function that it is used to find 
> the interface in the class is very slow and makes them not useable for high 
> performance situations. Is there a better way to do this or should I not use 
> interfaces like this in FPC?

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal