3D PLM Enterprise Architecture

Middleware Abstraction

Creating a Backbone Simple Message

Creating a message that doesn't convey any data
Use Case

Abstract

This article shows how to create a backbone simple message component, that is, a message component that doesn't convey any data. This message component can then be used to make two processes or applications communicate.


What You Will Learn With This Use Case

This use case shows you how to create a backbone simple message, that is, that doesn't convey any data. This use case shows how to create a component that derives from the base message component  CATBBMessage, and that implements, in the component main class, the CATIStreamMsg interface with no data to stream or unstream. In addition, it shows you how to implement CATICreateInstance using a code extension class to enable clients to instantiate the message component.

[Top]

The CAASysBBMessage Use Case

CAASysBBMessage is a use case of the CAASystem.edu framework that illustrates the System framework capabilities.

[Top]

What Does CAASysBBMessage Do

The message component is named CAASysSimpleMessage and derives from the CATBBMessage component. CAASysSimpleMessage implements the CATIStreamMsg and CATICreateInstance interfaces. It also inherits the implementation of the CATICommMsg and CATIBBStreamer interfaces from CATBBMessage. CATICreateInstance is implemented using a code extension class.

The CAASysBBMessage use case also includes another backbone message component that conveys data  [1].

[Top]

How to Launch CAASysBBMessage

CAASysBBMessage is launched by other backbone use cases [2][3], but you need to create the CAASysBBMessage shared library or DLL. To do this, you will need to set up the build time environment, and compile CAASysBBMessage along with its prerequisites [4].

[Top]

Where to Find the CAASysBBMessage Code

The CAASysBBMessage use case is made of several classes located in the CAASysBBMessage.m module of the CAASystem.edu framework:

Windows InstallRootDirectory\CAASystem.edu\CAASysBBMessage.m\
Unix InstallRootDirectory/CAASystem.edu/CAASysBBMessage.m/

where InstallRootDirectory is the directory where the CAA CD-ROM is installed.

[Top]

Step-by-Step

To create a backbone simple message, there are three main steps:

# Step Where
1 Creating the message component main class LocalInterfaces\CAASysSimpleMessage.h
src\CAASysSimpleMessage.cpp
2 Creating the message component factory LocalInterfaces\CAAESysCreateInstanceForSimpleMessage.h
src\CAAESysCreateInstanceForSimpleMessage.cpp
3 Updating the interface dictionary CNext\code\dictionary\CAASystem.edu.dico

[Top]

Creating the Message Component Main Class

A backbone message is a component that is made up of a main class. Its header file is as follows:

#include "CATBBMessage.h" 

class  CAASysSimpleMessage : public CATBBMessage
{
   CATDeclareClass;
   public:
      CAASysSimpleMessage();
      virtual ~CAASysSimpleMessage();

      // CATIStreamMsg Interface methods
      virtual HRESULT UnstreamData  (void  *iBuffer, uint32  iLen);
      virtual HRESULT StreamData    (void **oBuffer, uint32 *oLen);
      virtual HRESULT FreeStreamData(void  *iBuffer, uint32  iLen);
      virtual HRESULT SetMessageSpecifications();
  
  private:
      CAASysSimpleMessage(const CAASysSimpleMessage &iObjectToCopy);
};

The CAASysSimpleMessage class belongs to a component, thanks to the CATDeclareClass macro. It C++ derives from CATBBMessage, and implements CATIStreamMsg, whose four methods are declared. Note that the copy constructor is set as private, and is not implemented in the source file. This prevents the compiler from creating the copy constructor as public without you know.

The source file of the backbone simple message component main class is as follows:

#include  "CAASysSimpleMessage.h"
#include "CATICommMsg.h" // To set message specifications
#include <CATErrorDef.h> // for SUCCEEDED macro

#include "TIE_CATIStreamMsg.h"
TIE_CATIStreamMsg(CAASysSimpleMessage);

CATImplementClass(CAASysSimpleMessage, Implementation, CATBBMessage, CATNull);

CAASysSimpleMessage::CAASysSimpleMessage() {}

CAASysSimpleMessage::~CAASysSimpleMessage() {}

HRESULT CAASysSimpleMessage::StreamData(void **oBuffer, uint32 *oLen)
{
  *oBuffer = NULL;
  *oLen = 0;
  return S_OK;
}

HRESULT CAASysSimpleMessage::UnstreamData(void *iBuffer, uint32 iLen)
{ return S_OK; }

HRESULT CAASysSimpleMessage::FreeStreamData(void *iBuffer, uint32 iLen)
{ return S_OK; }

HRESULT CAASysSimpleMessage::SetMessageSpecifications()
{
  HRESULT ret = E_FAIL;
  CATICommMsg * pICommMsg = NULL;
  ret = QueryInterface(IID_CATICommMsg, (void**)&pICommMsg);
  if ( SUCCEEDED(ret) )
  {
    CATMessageClass MessageClassName = "CAASysSimpleMessage";
    ret = pICommMsg->SetMessageClass(MessageClassName);
 
    pICommMsg->Release();
    pICommMsg = NULL;

    ret = S_OK;
  }
  return ret ;
}

The CAASysSimpleMessage class states that it implements the CATIStreamMsg interface thanks to the TIE_CATIStreamMsg macro The CATImplementClass macro declares that the CAASysSimpleMessage class is a component main class thanks the Implementation keyword, and that the component OM-derives [5] from CATBBMessage. Any component main class declared as an Implementation must C++-derive and OM-derive from the same class. The CATIStreamMsg interface methods need only a simple implementation, since there is no data to convey with the message. StreamData returns a NULL buffer with a length of 0, UnstreamData and FreestreamData are empty, and SetMessageSpecifications declares the message component name as the message specifications.

[Top]

Creating the Message Component Factory

As any component, a backbone message should provide a means for any client application to instantiate it [6]. This is made possible by making the component implement CATICreateInstance using a code extension class. Below is the header file of this class.

#include "CATBaseUnknown.h"   //Needed to derive from CATBaseUnknown

class CAAESysCreateInstanceForSimpleMessage : public CATBaseUnknown
{
  CATDeclareClass;
  public:
    CAAESysCreateInstanceForSimpleMessage();
    virtual ~CAAESysCreateInstanceForSimpleMessage();

    // CATICreateInstance method 
    virtual HRESULT __stdcall CreateInstance(void **oppv);

  private:
    CAAESysCreateInstanceForSimpleMessage(const CAAESysCreateInstanceForSimpleMessage &iObjectToCopy);
};

The CAAESysCreateInstanceForSimpleMessage class belongs to a component, thanks to the CATDeclareClass macro. It C++ derives from CATBaseUnknown, and implements CATICreateInstance, whose unique method CreateInstance is declared. Note that the copy constructor is set as private, and is not implemented in the source file. This prevents the compiler from creating the copy constructor as public without you know.

The source file of this code extension class is as follows:

#include "CAAESysCreateInstanceForSimpleMessage.h"

#include "CAASysSimpleMessage.h"

#include "TIE_CATICreateInstance.h"
TIE_CATICreateInstance(CAAESysCreateInstanceForSimpleMessage);

CATImplementClass(CAAESysCreateInstanceForSimpleMessage,
                  CodeExtension,
                  CATBaseUnknown,
                  CAASysSimpleMessage);

CAAESysCreateInstanceForSimpleMessage::CAAESysCreateInstanceForSimpleMessage() {}

CAAESysCreateInstanceForSimpleMessage::~CAAESysCreateInstanceForSimpleMessage() {}

HRESULT __stdcall CAAESysCreateInstanceForSimpleMessage::CreateInstance(void ** oppv)
{
  CAASysSimpleMessage * pt = new CAASysSimpleMessage();
  if (!pt) return(E_OUTOFMEMORY);
  *oppv = (void *)pt;
  return(S_OK);
}

The CAAESysCreateInstanceForSimpleMessage class states that it implements the CATICreateInstance interface thanks to the TIE_CATICreateInstance macro. The CATImplementClass macro declares that the CAAESysCreateInstanceForSimpleMessage class is a code extension class, thanks to the CodeExtension keyword, and that it extends the component whose main class is CAASysSimpleMessage. The third parameter must always be set to CATBaseUnknown, makes no sense, and is unused for extensions. The CreateInstance method instantiates and returns the component main class.

[Top]

Updating the Interface Dictionary

The interface dictionary is updated as follows.

CAASysSimpleMessage         CATIStreamMsg           libCAASysBBMessage
CAASysSimpleMessage         CATICreateInstance      libCAASysBBMessage

The interface dictionary is a file whose name is the framework name suffixed by dico, such as CAASystem.edu.dico, and that you should create or update in the framework CNext\code\dictionary directory. The interface dictionary declares that the CAASysSimpleMsg component implements CATIStreamMsg and CATICreateInstance, and that the shared library or DLL to load to query pointers to these interfaces is libCAASysBBMessage.

[Top]


In Short

This use case has shown how to create a backbone simple message that can be used to communicate between two applications. As any backbone message, the message is made up of a component that derives from the supplied CATBBMessage component, that itself implements CATIStreamMsg and CATICreateInstance interfaces, and that inherits from CATBBMessage the implementation of the CATICommMsg interface. Such a message that doesn't convey any data has a very simple implementation of the CATIStreamMsg interface. It is now ready to be used by applications [2].

[Top]


References

[1] Creating a Backbone Data Message
[2] Sending a Simple Message to an Application
[3] Sending a Data Message to an Application
[4] Building and Launching a CAA V5 Use Case
[5] Object Modeler Component and Implementation Inheritances
[6] Creating Components
[Top]

History

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

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