Wednesday, March 18, 2009

Virtual-Abstract objects as Interfaces

In my last post i exposed a method to share objects between Dll's and applications. As i wrote in that post, the compiler doesn't know the type of received object (it assumes it's a pointer), so you must cast it to the correct type. In the code below, i casted it to TObject only to be sure it compiles correctly:
(* Initialize exported class *)
myObj := TObject(_EC).create;
(* work with exported class
:
:
... and free exported class *)
myObj.free;
This aproach allows you to create objects inside Dlls (in some cases it's all you need), but compiler can't access public methods and properties of the object because it doesn't know the object's type.

Delphi & Kylix developers can argue (with reason) that if you use Packages (bpl's) instead of Dll's you can share objects and the compiler will intelligently know wich is the type of shared objects. But if applications must compile in FreePascal in addition to that compilers you have to devise a workaround.

Well, the workaround is to create an interface who'll allow the compiler to access objects methods and properties. Object Pascal knows two Interface types, COM Interfaces and CORBA interfaces wich i'm not going to explain here, and a third one that isn't really an Interface type but works the same way is called Virtual-Abstract Objects, it will help you with code portability.

To define a Virtual-Abstract Object you have to create a class with all of it's methods virtual and abstract as this code shows:
Type
TAgeCalculator = Class
public
function GetAge: Integer; virtual; abstract;
procedure SetAge; virtual; abstract;
end;
Abstract means that the implementation of the object doesn't have to be in the same level of inheritance of the interface, but inherited to be implemented. Virtual means methods can be oberriden.

As an example, if you need to share objects between Dll's and must access to methods and properties, you have to include the class definition (like TAgeCalculator) in both units, the one wich implements the methods and the one wich access to the instance.

In my next post i'll include a complete example of this.

No comments: