3D PLM Enterprise Architecture

Middleware Abstraction - Object Modeler

Creating Interfaces

The way to expose your component behavior
Technical Article

Abstract

This article introduces the interfaces. It describes their role in the Object Modeler, of what they are made, and how to use them.


What Are CAA V5 Interfaces?

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:

Top

What Is an Interface Made of?

Top

A Sample Interface

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.

Top

The Interface Header 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:

Top

The Interface Source File

The 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:

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:

  1. QueryInterface returns a pointer to an interface from another pointer to another interface implemented by the same object
  2. AddRef adds a reference to a counter for this interface
  3. Release 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].

Top

The Interface TIE

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

Top

IUnknown and CATBaseUnknown

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:

  1. QueryInterface returns a pointer to an interface from another pointer to another interface implemented by the same component
  2. AddRef adds a reference to a counter for this interface
  3. Release 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.

Top


In Short

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.

Top


References

[1] What Is HRESULT?
[2] About __stdcall
[3] About Globally Unique IDentifiers
[4] Using Components
[5] Interface Quick Reference
[Top]

History

Version: 1 [Jan 2000] Document created
[Top]

Copyright © 2000, Dassault Systèmes. All rights reserved.