3D PLM Enterprise Architecture |
Middleware Abstraction - Object Modeler |
Creating InterfacesThe way to expose your component behavior |
Technical Article |
AbstractThis article introduces the interfaces. It describes their role in the Object Modeler, of what they are made, and how to use them. |
Object-oriented design and related object-oriented languages such as C++ allow the application programmer to describe and code real objects as classes tha include a structural part, the data members, and a behavioral part, the member functions, or methods. With C++, the classes are instantiated using their constructors and the application programmer who uses the classes can reference the data members and the methods declared as public, and can also use the data members and the methods declared as protected when deriving the classes to build new ones. This is a very nice object-oriented feature, but when the header file of a class changes, even if only the private part changes, all the applications that include this file must be rebuilt.
A more generic way to design objects is to see them through their behavior only, and to describe this behavior by means of methods only: this provides interfaces to grasp the object. For the application programmer, the interface is the only visible part of an object that hides the details of its implementation which are totally under the responsibility of the class provider.
The interface constitutes a contract between the framework class developer and the application programmer. This contract includes the object from the real world to work on, the methods to use to manipulate these objects and how to call these methods. This should not change with the time. Only additions are allowed, and the applications developed on top of the framework should never been rebuilt due to framework modifications.
Implementing an interface is the way the framework class developer meets the contract. It is his/her own business to choose the most appropriate technology, and possibly to switch from one technology to another when necessary without impact for the applications.
A supplied interface should not change with the time. A supplied implementation of an interface should also continue to implement the unchanged interface without modification for the client application with the time. If modifications are required, such as new method signatures, a new interface must be supplied. If other interfaces must be implemented, existing implementations should not change, and CAA V5 provides means to extend them without impact for the client application.
The needs that suit the interface and implementation separation are the following:
A CATIA interface is created as a C++ abstract class. It thus contains only pure virtual methods. It is made of a header file, a source file, and a TIE file.
Here is how the CAAIXX CATIA interface header file looks like:
#ifndef CAAIXX_h #define CAAIXX_h #include "CATBaseUnknown.h" extern ExportedByCAADLL IID IID_CAAIXX; class ExportedByCAADLL CAAIXX : public CATBaseUnknown { CATDeclareInterface; public : virtual HRESULT __stdcall MXX1() = 0; virtual HRESULT __stdcall MXX2(CATBaseUnknown * pUnk) = 0; }; #endif |
The role of each statement is depicted below.
These roles are:
#ifndef
, #define
, and #endif
preprocessor directives protect the header file from multiple inclusion.CATDeclareInterface
declares that this class is a
CATIA interfaceThe CAAIXX interface source file is as follows.
#include "CAAIXX.h“ IID IID_CAAIXX = { 0x7c1b4ba8, 0x5c25, 0x0000, {0x02, 0x80, 0x02, 0x0b, 0xcb, 0x00, 0x00, 0x00} }; CATImplementInterface(CAAIXX, CATBaseUnknown); |
The role of each statement is depicted below.
These roles are:
CATImplementInterface
declares that CAAIXX
OM-derives from CATBaseUnknown. Interfaces must always OM-derive
from CATBaseUnknown.The pure virtual functions are of course not implemented in the classes which declare them as pure.
Among the methods of CATIXX
, three methods inherited from the
interface IUnknown
, from which derives the class CATBaseUnknown
,
play a particular role for an interface:
QueryInterface
returns a pointer to an interface from another
pointer to another interface implemented by the same objectAddRef
adds a reference to a counter for this interfaceRelease
removes the reference from the counter.QueryInterface
allows for navigation among the interfaces
implemented by a component, while AddRef
and Release
allow for component life cycle management [4].
The third file to create requests that the interface TIE be generated by the code builder mkmk. This file is the TIE_CAAIXX.tsrc file that simply contains an include statement to the CAAIXX.h file:
#include "CAAIXX.h" |
The TIEs is not part of the object model concepts. It is a necessary
implementation detail. To separate interfaces from their implementations, a TIE
object instance is created at run time as an intermediary object that makes the
link between the component that uses the interface and thus holds a pointer to
this interface, and the component that implements the interface, that is, that
contains the code to run the methods declared by the interface. The interface
pointer is in fact a pointer to a TIE object instance returned by the QueryInterface
method. The TIE object redirects the interface method calls to the component
that implements the interface.
The TIE file is by default created in the ProtectedGenerated folder, whatever the interface header file location. To create it in the PublicGenerated folder, add the //public keyword in the tsrc file, as follows:
#include "CAAIXX.h" //public |
The base class for all interfaces and for all classes that implement interfaces is CATBaseUnknown, a class provided by CATIA. CATBaseUnknown derives from the IUnknown interface, supplied by CATIA for UNIX and by the Microsoft's Component Object Model (COM) for Windows. The IUnknown interface is as follows:
interface IUnknown { virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) = 0; virtual ULONG __stdcall AddRef() = 0; virtual ULONG __stdcall Release() = 0; }; |
Among the methods of CAAIXX, these three methods inherited from the interface IUnknown play a particular role:
QueryInterface
returns a pointer to an interface from another
pointer to another interface implemented by the same componentAddRef
adds a reference to a counter for this interfaceRelease
removes the reference from the counter.QueryInterface
allows for navigation among the interfaces
implemented by a component, while AddRef
and Release
allow for component life cycle management.
The IUnknown interface supplied by CATIA is exactly the same that the one of COM, making interfaces portable from UNIX to Windows and the reverse.
CATBaseUnknown provides an implementation for the methods QueryInterface
,
AddRef
and Release
, exposed as pure virtual functions
by IUnknown, avoiding to implement them whenever you implement an
interface and thus contributing to code factorization.
All interfaces can be seen as IUnknown interfaces, that is a pointer to IUnknown can be used for each of them . This allows the client application to request from such an IUnknown pointer if the implementing component supports other interfaces and prevents the client application to manage pointers to those implementing objects, managing only pointers to interfaces.
CATIA interfaces as created as C++ absract classes deriving from CATBaseUnknown. The interface TIE makes the link at run time between the component that uses the interface and the component that implements it.
The interface is a contract between the interface developer, the provider of the component that implements the interface, and the client application programmer who uses the component. The interface should not change with the time, and the client applications which use these interfaces never need to be rebuilt when a new version of the code which contains the interface implementations is installed.
[1] | What Is HRESULT? |
[2] | About __stdcall |
[3] | About Globally Unique IDentifiers |
[4] | Using Components |
[5] | Interface Quick Reference |
[Top] |
Version: 1 [Jan 2000] | Document created |
[Top] |
Copyright © 2000, Dassault Systèmes. All rights reserved.