PDA

View Full Version : Casting an object to an interface



ianatwork
10-02-2009, 11:37 AM
I need to store references to interfaces in a list so that when the user selects a list item I can easily access the interface that relates to that item. I’ve been casting the interface as a pointer and adding it as the list items object. Now when I try to retrieve it I try to cast it back and the compiler moans that you cant cast a TObject to an interface. I tried casting it to a pointer first and then to the interface type which the compiler likes (see code below). The problem I have then is that when the code runs, when the following line runs it throws an exception. My question is, Is there a better way to do what I need to do and what is causing the problem with this code. I must say that I’m not 100% when it comes to interfaces. :(

Item := IJanusDataSourceItem (pointer (ListItemObject)) ;

JSoftware
10-02-2009, 02:02 PM
Can't you just use the TInterfaceList from the classses unit?

chronozphere
10-02-2009, 02:04 PM
You could:

* Take a look at TInterfaceList. This is probably the best option as it will give you an idea how to use interfaces on a list. You could also just use the class itsself and get rid of TList.

* Cast your pointer back to TInterfacedObject (If you were deriving your implementation from that class) and call QueryInterface(). This will give you your interface back. :)

Hope this was helpfull. ;)

ianatwork
10-02-2009, 03:26 PM
Can't you just use the TInterfaceList from the classses unit?

I should probably explain my problem in greater detail as using an interface list will not work for me. I need to populate a visible list of data (a listview or string grid) that a user can select from. Each item comes from an enumeration of IJanusDataSourceItem. I wanted to store each interface reference with each item in a listview control so that when the user presses a button I can easily grab the appropriate interface which contains further details. The data in the IJanusDataSourceItem’s can change at runtime so the listview will change with new data being added or removed as well as the visual textual content being changed. I have no control over the IJanusDataSourceItem as these come from a C++ dll. If I use an interface list I then need to reference that list in my listview, I would also need to maintain the integrity between the two lists if data was added or removed. I hope that explains my problem a little better. The key point is that I need to show some data from the interface in a listview or string grid but also to be able to maintain a link between the visual content and the interface to update changes to the interface content etc.

jdarling
10-02-2009, 10:59 PM
TListItem.Tag := PtrInt(@Interface); // cast and store don't remember it might be .data

@Interface := pointer(PtrInt(TListItem.Tag)); // and away you go

Don't remember if that works in Delphi, but its a treat in Lazarus.