[Previous] [Next] [Contents] [Index]


    The CORBA Integration

In this chapter, the integration of SDL applications with CORBA is described. Initially, a general overview of the solution is provided, and is followed by a more elaborate description of the different aspects involved. A set of rules is given for how IDL is mapped to SDL, both to increase the understanding of how the integration is supposed to work, and to facilitate the manual operations that are sometimes necessary.

This chapter also outlines how an application should be created that is accessible from clients through CORBA, and which can also address other CORBA servers.

In the end of this chapter, a few technical issues are discussed, such as how the Master Library (see The Master Library) is affected. The CORBA Tutorial, further describes in some detail how a CORBA application can be created.

Table of Contents 

Introduction

This chapter is about how CORBA (The Common Object Request Broker: Architecture and Specification) is integrated with applications generated by SDT.

To begin with, some different approaches to perform such an integration are described in Integrating CORBA with SDL.

After that, the mapping rules that should be used when transforming IDL (Interface Definition Language) to SDL are described in Mapping IDL to SDL. IDL is an abstract language that is used to describe the interfaces of objects; these objects are then represented in SDL, which is where the behavior of the objects is implemented. In particular, this section also describes a special package, containing SDL versions of CORBA types, that must be used by all SDL systems that are turned into CORBA applications.

In the following section, Creating an Object Implementation, it is described how an SDL application is actually created, and this is immediately followed by a section on how other servers can be addressed through CORBA from the SDL application (in Using Other CORBA Objects).

After that, some technical sections follow, such as The IDL Compiler, where it is shown how an IDL compiler can be used to automatically create a stub utilizing the IDL to SDL mapping rules. Only types can be generated, which means that the behavior of the types must be implemented before it is possible to generate an application.

In The Environment it is then showed how the SDL application is encapsulated by wrappers on both the client side and the server side, and how the environment functions are used to mediate messages between the SDL system and the wrappers.

The Master Library describes the additions that have been made to the Master Library. This includes an account of the new libraries that are created and that must used when creating a CORBA application, but also of the functions and types that have been added to facilitate communication with the C++ wrapper.

Requirements

The platform and tool requirements for the CORBA integration is as follows:

Platform ORB

Sun Solaris 2.5

Orbix 2.1mt, with SPARCompiler C++ 4.x

Integrating CORBA with SDL

When integrating CORBA with SDL there are basically two ways to go about this:

These approaches might appear very similar at first, but the methodologies used are different as will be seen in the subsequent sections. In SDT, only the first approach is currently supported.

The CORBA-Oriented Approach

The CORBA-oriented approach is primarily used when SDL is viewed as a design (implementation) language, and a given IDL description should be designed using SDL, as is depicted in Figure 505.

Figure 505  : The CORBA-oriented approach

Extracted pic [3]

The basic activities when building a system using the CORBA-oriented approach are:

  1. Transform the IDL description into an SDL stub (i.e., a skeleton).
  2. Define the behavior of the SDL system by adding information to the SDL stub from above.
  3. Make the executable SDL application (using the appropriate make switches).

A system created using the CORBA-oriented approach is intended as a part of a larger distributed system, the components of which might be defined using other languages than SDL, as is exemplified in Figure 506. Each of the different SDL applications contains one or more SDL processes.

Figure 506  : An example of a distributed system using CORBA

Extracted pic [4]

The concepts introduced here are further elaborated in section Creating an Object Implementation.

The SDL-Oriented Approach

Note: 

The SDL-oriented approach is not supported in SDT; a brief overview is included here mainly to give an understanding of what is supported and what is not.

The SDL-oriented approach is primarily used when SDL is viewed as a specification language. Once the specification of the entire distributed application has been performed in SDL, it should be partitioned into arbitrarily small subsystems that are then (optionally) implemented on different machines and which communicate with each other using CORBA as underlying messaging mechanism. The smallest unit of partitioning is an SDL process.

Figure 507 : The CORBA-oriented approach

Extracted pic [5]

The process of creating a system using the SDL-oriented approach is seemingly simple:

  1. Define an SDL system.
  2. Make the executable SDL application (using the appropriate make switches). IDL interfaces between the relevant parts are automatically generated, and not necessarily visible.

In the SDL-oriented approach, the SDL system contains the entire distributed system, where SDL processes communicate with each other through CORBA. Compare this approach with the targeting of SDL applications on a real-time OS, as is described in a separate manual.

Figure 508 : An SDL system targeted on CORBA

Extracted pic [6]

Mapping IDL to SDL

An important part of the CORBA-oriented approach is to transform an IDL description into an SDL stub. In order to do this the same way every time it is necessary to have mapping rules describing how this transformation should be performed.

IDL is a language used for describing interfaces abstractly, and its definition can be found in The Common Object Request Broker: Architecture and Specification (CORBA) standard that is issued by OMG.

The IDL description cannot be used by itself, but is always mapped to a target language. CORBA specifies mapping rules from IDL to several target languages, such as C++ and Smalltalk. When using SDT, this target language is SDL, and the mapping rules are presented in this section.

Note: 

The mapping rules given here are not standardized, and may be subject to change in future releases.

The textual Phrase Representation of SDL (SDL/PR) is used to describe SDL concepts throughout this section.

General Mapping Structure

The package concept of SDL is utilized to describe the mapping from IDL to SDL, and the end result depends on whether the IDL description is used to define an SDL implementation or to access other servers in the CORBA environment. In the first case, the SDL system implements the IDL description, while in the second case it makes use of an IDL description that is implemented elsewhere using some arbitrary target language.

The two packages that are used in SDL are an interface package and a definition package.

An IDL description consists of one or more text files using the extension.idl, and one of these is always considered the main file from which the other files are included in the same manner as C++ header files are included. In this chapter, when an IDL file is mentioned, it is always as the main file of an IDL description.

The interface package contains interface specifications in the form of for example data types, signals, remote procedures, synonyms, and signal lists. This package is always generated from an IDL description, and represents information that is externally visible. The interface package is named after the IDL file that was used, and the suffix _interface is always appended to the name. This resembles the way a C++ header file is used in the IDL C++ mapping.

The definition package contains structure information that is inherent in the IDL description in the form of modules and interfaces, and it also contains a system type which can be instantiated when behavior has been added. The definition package is only generated from an IDL description if a new server should be created in SDL. The definition package is also named after the IDL file that was used, and the suffix _definition is always appended to the name. The system that is defined in this package is also named after the IDL file, but with the suffix _system appended instead. The definition package always uses the interface package. This resembles the way a C++ source file is used in the IDL C++ mapping.

Note: 

Since IDL is an abstract language it contains no behavioral information, which consequently has to be added to the SDL system once the initial transformation has been performed. Examples of behavior that must be added are how block types and process types should be instantiated, how they should be interconnected using signalroutes and channels, and what procedures and transitions are expected to do.

Finally, the system type is instantiated using the name of the IDL file.

Consider the example IDL file name.idl. When implementing a server based on this description, the corresponding (transformed) SDL system would look like:

IDL SDL
name.idl
use idltypes;
package name_interface;
    /* interface definition */
endpackage;

use idltypes;
use name_interface;
package name_definition;
    system type name_system;
        /* behavior definition */
    endsystem type;
endpackage;

use name_definition;
system name : name_system;

Note that the definition package must make use of the interface package to be valid. Furthermore, the predefined package idltypes must always be used. This package contains SDL types that represent the basic IDL types.

If the IDL description represents a server that has already been implemented somewhere else, and will only be used to access that server from the SDL system being implemented, the same IDL file (name.idl) is mapped like:

IDL SDL
name.idl
use idltypes;
package name_interface;
    /* interface definition */
endpackage;

Note that only the interface package is generated in this case.

In the mapping rules given below it will be indicated whether a definition should be part of the interface or the behavior package.

Scoped Names

When an identifier is mapped from IDL to SDL, there is a problem with names being able to clash with other names.

For example, consider an interface in which a new type is defined. This type cannot be defined inside the corresponding SDL entity because then it would not be visible at the system level where signals and remote procedures might want to use it for its parameters. For this reason, the type must be defined at (i.e., moved to) the system level. Since all definitions must be made at the system level, there is a possibility that multiple definitions using the same name are made (e.g., if two interfaces contain different type definitions using the same name).

In order to avoid this problem, global names are enforced in all mappings from IDL to SDL, i.e., each occurrence of "::" in the global name is replaced with an `_' (underscore), and then the leading underscore is removed. This is the general way of handling global names that is specified in CORBA.

Modules

A module is mapped to a block type, where nested modules become nested block types.

IDL SDL
module M {
};

module N1 {
  module N2 {
  };
};
/* definition package */
block type M;
endblock type;

block type N1;
  block type N1_N2;
  endblock type;
endblock type;

Interfaces

An interface is mapped to a process type. If the interface is defined within a module, the process type is defined within the corresponding block type.

IDL SDL
interface I {
};

module M {
  interface I {
  };
};
/* definition package */
process type I;
endprocess type;

block type M;
  process type M_I;
  endprocess type;
endblock type;

Object References

An object reference, i.e., a reference to an object implementing an interface, is mapped to the type PId.

Exceptions

Note: 

Exceptions are currently not supported.

Operations

An operation is mapped differently to SDL depending on whether it is asynchronous or synchronous, i.e., whether it is defined using the IDL keyword oneway or not.

Caution! 

In order to prevent problems with name clashing, operation names starting with "get_" or "set_" should generally be avoided (see Attributes for more information on this subject).

Asynchronous and Synchronous Operations

Each asynchronous operation (which in IDL is defined using the keyword oneway) is mapped to a pair of one signal and one procedure, while a synchronous operation is mapped to a remote procedure.


Example 407 : Mapping of operations      

A remote procedure can be called from the environment, or the SDL system can call a remote procedure defined in the environment (this is standardized in SDL-96).

It is required that the paths leading to or from the environment (signalroutes and channels) contain the remote procedures that can be called (possibly with the keyword procedure to distinguish them from signals).

Operation Parameters

An IDL operation can carry three kinds of parameters: in-, inout-, and out-parameters, whereas only two kinds are available in SDL: in- and in/out-parameters. The mappings between these parameter kinds are straightforward:

IDL SDL
in
inout
out
in
in/out
in/out

An operation return type is mapped to a corresponding remote procedure return.


Example 408 : Mapping of operations      

The mapping rules of the types that appear in the above example can be found in Types.

Raises Expressions

Note: 

Raises expressions are not supported.

Context Expressions

Note: 

Context expressions are not supported.

Attributes

An attribute is mapped to a variable declaration and a pair of remote procedures to set and get the value of the variable. The accessor functions are named by appending the attribute with a prefix: get_ or set_.

Caution! 

The practice of appending prefixes makes it possible for name clashes to occur if an operation should happen to have the same name. To avoid this problem, do not use get_ or set_ in operation names.

If the attribute is defined as readonly, the remote procedure to set the variable is omitted.

The behavior of the remote procedures is well defined for attributes, and can therefore be included in the mapping rules. For set-operations, the attribute value should be assigned a new value, while for get-operations, the attribute value should only be returned.


Example 409 : Mapping of attributes      

Inheritance

IDL inheritance cannot be mapped to SDL inheritance; instead, inheritance must be represented using a flat structure, where all procedures corresponding to operations and attributes defined in a base process type must be duplicated in a derived process type.

By using the above approach, it is also possible to support multiple inheritance.


Example 410  : Mapping of inheritance      

Constants

A constant is mapped to a synonym.


Example 411 : Mapping of constants      

Types

Each IDL type has a corresponding SDL type. In some cases, the SDL type is predefined, and in other cases it has to be generated based on the IDL specification.

SDL types based on the basic IDL types are available in a predefined package (idltypes) in the same manner as ordinary SDL types are available from a predefined package.

The package containing the predefined CORBA types should be used by all packages and systems that are part of an CORBA application.

Basic Types

Basic IDL types are typical examples of types that are predefined in SDL. All CORBA types are defined as syntypes of existing SDL types, according to the following table:

IDL SDL syntype of

long
CORBA_long
Integer

short
CORBA_short
Integer

unsigned long
CORBA_unsigned_long
Integer

unsigned short
CORBA_unsigned_short
Integer

double
CORBA_double
Real

float
CORBA_float
Real

char
CORBA_char
Character

boolean
CORBA_boolean
Boolean

octet
CORBA_octet
Octet1


1. Octet is not an SDL type according to Z.100, but is part of Z.105 as an ASN.1 type.

Note: 

The basic IDL type any is not supported.

Type Definitions

A typedef is mapped to a syntype.


Example 412 : Mapping of type definitions      

Enums

An enum is mapped to a literal type.


Example 413 : Mapping of enumerations      

Structs

A struct is mapped to a struct type.


Example 414 : Mapping of structures      

Unions

Note: 

The type union is not supported in SDL.

Sequences

A sequence is mapped to a string, regardless of whether it is bounded or unbounded.


Example 415 : Mapping of sequences      

Strings

A string is mapped to SDL as is shown in the following table, regardless of whether the string is bounded or unbounded:

IDL SDL syntype of
string
CORBA_string
Charstring

The SDL type CORBA_string is present in the package idltypes.


Example 416 : Mapping of strings      

Arrays

An array is mapped to an array.

For each array, however, it is necessary to define a specific range type, whose index goes from 0 to <size> - 1, where <size> is the number of elements specified for the IDL array.

Multi-dimensional arrays require multiple range specifications.


Example 417 : Mapping of arrays      

Creating an Object Implementation

The process of creating an object implementation is described in this section. When using the CORBA-oriented approach, development is assumed to start with an IDL description, and then to proceed using the following steps:

  1. Convert the IDL description to an SDL stub. This stub contains no behavior.
  2. Provide the behavior of the SDL system, and then simulate and validate the behavior of it.
  3. Generate an application (object implementation) from the SDL system, and register it with the ORB.

These steps are further elaborated below.

Creating an IDL Description

The first step in creating an SDL application capable of being used in a CORBA environment is to produce the IDL description that is supposed to be implemented. The three most obvious ways to obtain an IDL description are:

Using an Existing IDL Description

If the IDL description already exists, it should be entered in the Organizer, which is done by using the menu command Add Existing. When this is done a file dialog pops up, where the appropriate IDL file should be selected. By pressing OK, the chosen file will appear in the Organizer as an IDL file in the Organizer.

Creating a New IDL Description

To create a new IDL description, the menu command Add New should be used; in the popup dialog a document of type Text IDL should then be chosen. It is customary to use the suffix .idl when naming an IDL file.

When pressing OK, the IDL file appears in the Organizer, and a text editor where the file can be created is also displayed on the screen.

Using Copy/Paste As to Create an IDL Description

The previous approach of creating an IDL description can be combined with the copy/paste as concept that is defined in the SOMT method.

In that case, it is possible to copy classes from the Object Model Editor, and then to paste them as IDL modules or interfaces in the file that has been opened in the text editor.

The mapping rules that are used are very simple; if a class is mapped to an IDL module, the module will be empty (regardless of whether the class contained attributed or operations). If, on the other hand, a class is mapped to an IDL interface, the attributes and operations of the class will become attributes and operations of the interface.

However, it is not possible to deduce all properties of the IDL description from the Object Model, which means that some properties must be manually added to the IDL description once the transformation from the Object Model has been performed.

For more information about this subject, please refer to the volume SOMT Methodology Guidelines.

Converting an IDL Description to an SDL System Skeleton

There are then several ways to convert the IDL description into an SDL stub:

Once the IDL description has been converted, the SDL system should be entered into the Organizer.

Convert IDL to SDL

When the menu command Convert IDL to SDL is used from the Organizer, a dialog pops up. In this dialog, the main file name of the IDL description should be used as source file. Furthermore, since it is an implementation that is being created, code should be generated for a server, and all names should be global. If it is needed, the target directory where the resulting files will be placed can also be specified. All of these options are further described in The IDL Compiler.

Figure 509 : The Convert IDL to SDL dialog

Extracted pic [1]

Once the appropriate IDL file has been selected, and the options have been set, the actual conversion is started by pressing Convert.

This conversion will result in a set of files (see The File Structure for a description of these files), some of which describe the SDL system. These files are known as Graphical Representation (GR) files.

The generated SDL system is a stub (or skeleton) which contains no behavior at all.

If the IDL compiler is invoked from the command line, the approach is slightly different. In this case, the IDL compiler should be invoked as:

Both the server and global aspects are used by default. However, the compiler will only produce one file in textual Phrase Representation (PR), i.e., the SDL specification is represented as one textual file. Compare this with the Organizer approach, where a set of GR files were created. In the Organizer, it is then necessary to convert this PR file to a set of GR files, which is done by issuing the menu command Convert to GR, using the generated PR file as source file.

Import SDL

In order to view the resulting SDL system in the Organizer, the menu command Import SDL is used.

There are two things to keep in mind when importing the generated SDL system, and these are:

  1. The source file is named after the IDL file that was converted, except that it uses the suffix .ssy instead. If the IDL file was named name.idl, the file that should be imported is name.ssy.
  2. In the dialog that is used for this menu command, it is possible to specify Details. The first of the options in Details, i.e., Close the current system first, should be turned off. This will prevent the files already present in the Organizer to be removed prior to opening the new system that is imported.

The transformed IDL description will appear in the Organizer when Import is performed.

Providing Behavior to the SDL System

Since the converted SDL system is only a skeleton it is necessary to add behavior to it. This is not different from creating an ordinary SDL system, except that some of the work has already been automatically performed.

Caution! 

Do not alter the automatically generated names of the SDL system as this may cause the executable to behave incorrectly.

If changes are made to parameters and such in the SDL system, the corresponding parameters of the initial IDL description should also be altered accordingly.

When the behavior of the system has been provided it is possible to simulate and validate the application. Note that it is not possible to simulate the entire distributed system of which this SDL system might be only a part (compare with Figure 506).

Note: 

An SDL system skeleton should be generated only once. If behavior is added, and new functionality is entered in the IDL description, the SDL system should be manually updated according to the mapping rules given in Mapping IDL to SDL. If a new generation is performed, any behavioral aspects that had been added to the system are lost.

Generating a CORBA Application

Once the behavior of the SDL system has been satisfactorily provided it is time to create the final executable, which is the CORBA application that is eventually registered to the ORB. On order to create such an application, the menu command Make should be performed.

The Make Dialog

In the Make dialog, it is important to see to it that the appropriate options are set.

Figure 510 : Appropriate options in the Make dialog

Extracted pic [2]

In the section Analyze & generate code, the following options should be set:

Note: 

In order to make use of the CORBA support, it is necessary to have a license for Cadvanced.

Furthermore, Generate environment header file should also be turned on.

In the Makefile section, the Generate makefile and use template option should be chosen, where the template file to use is named after the IDL description (see The File Structure), but with the suffix .tpm. If the IDL file was called name.idl, the make template file to use is called name.tpm.

Finally, in the Compile & link section, the kernel to be used is found in the directory $sdtdir/SCTCORBA. More information about kernels can be found in The Master Library.

When all of these options have been checked, the application is created by pressing Make.

Registering the Application

If all goes well, an executable is created. Again, if the IDL file that was initially used was called name.idl, the executable would be named name_acx.sct.

This application usually has to be registered with an ORB to function as a part of a larger distributed system. In Orbix, the way to register an application is by using the shell command putit, e.g.,

It is recommended that the name of the server is the same as the name of the generated SDL system (in the case of name.idl, the server name should thus simply be name). If another server name is wanted, it is necessary to modify the function call xxSetServerName in the generated C++ wrapper file (this file is name_i.cc, as is shown in The File Structure). This function is used during the server initialization to set up the correct server name for when the ORB function impl_is_ready is called.

When the application has been registered, it is possible for clients to access the server, making use of the offered services. The application can be launched manually from a command shell, or automatically by Orbix in response to an incoming operation invocation.

Creating a Debug Application

When the CORBA application was created, the kernel SCTCORBA was used. It is possible to use the kernel SCTCORBASIM instead, which behaves approximately as the ApplicationDebug kernel that is described in The Master Library.

When using a debug application it is possible to trace all events in the SDL system using the simulator.

The creation process when creating a debug application is basically as is outline above. The only difference is that the server must be started as a persistent server, i.e., it must be manually launched before it can be accessed by the ORB. This can be done either from the Simulator UI, or from the command line by running the executable. It cannot, however, be started by a client through the ORB.

When the application has been opened in the simulator, the command start-env must be executed before the ORB is able to communicate with the ORB.

Using Other CORBA Objects

During the course of providing behavior to an SDL system, it might be found that there exists a CORBA server which provides some functionality that is needed. In such cases, it is useful to be able to request those services directly from the SDL system, i.e., to let the SDL system act as a client of that server.

The very few steps that are required to be able to achieve this include:

  1. Convert the IDL description to an SDL interface package.
  2. Use the converted SDL interface package in the SDL system.
  3. Add an entry in the system's make template file.

Converting an IDL Description to an SDL Interface Package

There are then a couple of ways to convert the IDL description into an SDL interface package:

Once the IDL description has been converted, the SDL system should be entered into the Organizer.

Convert IDL to SDL

When the menu command Convert IDL to SDL is used from the Organizer, a dialog pops up. In this dialog, the main file name of the IDL description should be used as source file. Furthermore, since the IDL description describes services that are to be used by a client, code should be generated for a client, and all names should be global. If it is needed, the target directory where the resulting files will be placed can also be specified. All of these options are further described in The IDL Compiler.

Once the appropriate IDL file has been selected, and the options have been set, the actual conversion is started by pressing Convert.

This conversion will result in a set of files (see The File Structure for a description of these files), where one GR file describes the SDL interface package that corresponds to the IDL description.

If an SDL system exists in the Organizer by the time of the conversion, the name of the system will be used in the generated header file of the C++ wrapper. If no SDL system exists, the generated header file will contain an entry of the form #include Untitled.ifc, which will have to be manually corrected by replacing "Untitled" with the actual system name.

If the IDL compiler is invoked from the command line, the approach is slightly different. In this case, the IDL compiler should be invoked as:

However, the compiler will only produce one file in textual Phrase Representation (PR), i.e., the SDL interface package is represented as one textual file. Compare this with the Organizer approach, where a GR file was directly created. In the Organizer, it is then necessary to convert this PR file to a GR file, which is done by issuing the menu command Convert to GR, using the generated PR file as source file.

Import SDL

In order to view the resulting SDL interface package in the Organizer, the menu command Import SDL is used.

There are two things to keep in mind when importing the generated SDL system, and these are:

  1. The source file is named after the IDL file that was converted, except that it uses the suffix _interface.sun instead. If the IDL file was named name.idl, the file that should be imported is name_interface.sun.
  2. In the dialog that is used for this menu command, it is possible to specify Details. The first of the options in Details, i.e., Close the current system first, must be turned off. This will prevent the files already present in the Organizer to be removed prior to opening the new system that is imported.

The transformed IDL description will appear in the Organizer when Import is performed.

Using the SDL Interface Package

The system that wishes to utilize the services offered by an IDL description should use the corresponding SDL interface package.

The operations that are available on the server are found in the interface package in the form of signals or remote procedures, and if an object reference (or PId value) of the server is known, a request can be sent in the form of a signal or a remote procedure to that PId value.

If, however, the object reference is not known, and the signal is sent without specifying a receiver, the signal will be sent to one server which implements that service. This server is located by the ORB, and when using Orbix, the _bind function is used to find it.

Adding to the Make Template File

When the application is generated, a make template file is used. The contents of this make template file is shown in The File Structure.

When implementing the server side of an application, this template file is automatically created. However, when using the client side of an application it is necessary to add a few entries in order to make the application correctly.

Basically, for each additional server that is used by the system, two new entries (object files) should be made, as is shown in the following table where the added entries are highlighted:

CORBA server(s) Contents of make template file
server.idl
serverOBJECTS = serverC.o server_c.o
server1.idl
server2.idl
serverOBJECTS = server1C.o server1_c.o \
                server2C.o server2_c.o

The first object file is generated by the ORB, while the second object file is generated by SDT. These must be present in the make template file for the compiled and linked application to be able to communicate through with other servers through the ORB.

The IDL Compiler

The mapping rules that are described in Mapping IDL to SDL must sometimes be used manually, for example when a change is made to the IDL specification once the corresponding SDL system has already been implemented.

When first creating the SDL system, however, it is advantageous to make use of the IDL compiler that accompanies SDT, sdtidl, to automatically generate code from an IDL specification.

The primary use of the IDL compiler is to generate an SDL stub from an IDL specification according to the mapping rules, but it is also used to generate the C++ wrappers that are needed for the CORBA application. In the Organizer, there is a dialog that can be used to invoke the IDL compiler (see Converting an IDL Description to an SDL System Skeleton). A summary of the most important flags to use when generating code is shown below (note that some of these flags can only be used when invoking the IDL compiler from the command line):

Flag Description

-V

Print version information.

-u

Print usage message.

-L<language>

Choose language to be generated. Possible values of <language> are sdl and c++.

-N<namescope>

Choose namescope to be generated. Possible values of <namescope> are global and local.

-S<side>

Choose side to be generated. Possible values of <side> are server and client.

-Wb<application>

Set the application name to be used in the generated header file of the C++ wrapper.

-T<targetdir>

Choose the target directory in which generated code should be placed.

The sdtidl compiler can be found in the directory $sdtbin.

Usage

The IDL compiler sdtidl is used to generate an SDL stub (skeleton), but also to generate SDT specific wrappers to the used ORB.

This ORB generally also has an IDL compiler of its own, which is used to generate stubs and skeletons needed by the ORB. However, the invocation of this external IDL compiler is implicit, and is made when the final application is being compiled (how the invocation is performed can be deduced from the makeoptions file (see The makeoptions File).

Flags

There are several switches that can be used to control the behavior of the IDL compiler, and these are described below.

Version

The version number of the IDL compiler can be found by using the switch -V:

When this switch is set, no other actions are performed.

Usage

All switches that are possible to use with the IDL compiler are shown if the switch -u is used:

No other actions are performed when this switch is used.

Generated Language

The IDL compiler is intended to produce an SDL stub according to the mapping rules in Mapping IDL to SDL. However, it is also used to produce the C++ wrapper (see The SDL System) and the make template file (see The Make Template File) for the SDL application.

As default, the following files are generated from an IDL specification (it is assumed that the IDL specification file is named name.idl):

In some cases, however, it is advantageous to produce only a subset of these files, and to achieve that the -L switch is used. This switch takes an argument that can be either c++ or sdl.

Only the C++ wrapper is produced (along with the make template file) when the -Lc++ option is used; this is particularly useful if there already exists an SDL system that should not be changed:

On the other hand, only the SDL stub is generated when the -Lsdl option is used; this is particularly useful when the SDL system should only be simulated, and not be made into an application:

If, at a later stage, the simulated SDL system should be turned into a CORBA application, it is only necessary to create the C++ wrapper using the -Lc++ switch.

Namescope

When generating SDL from IDL, it is possible to choose between two different modes: by default SDL names must be made global (see Scoped Names) in order to avoid discrepancies. It is not recommended to use local names due to this fact.

The switch -N is used to control the namescope, and it should be used together with an argument that is either global or local.

Note: 

The usage of -Nlocal is obsolete, and should not be used. This also means that the switch -N should never be used, as -Nglobal is used per default.

Application Side

When using the IDL compiler, it is possible to denote whether the produced code should be used on the client or the server side of the application. By default, code is generated for the server side.

By using the switch -S it is possible to choose side by using either of the arguments server and client.

Thus, in order to produce code for only the client side of the system, the following command should be given:

Application Name

When generating code for the client side, i.e. when using -Sclient, you can specify in which SDL system the IDL specification will be used. In this way, the generated header file of the C++ wrapper will include the correctly named .ifc file for the system. This is done by using the switch -Wb directly followed by the SDL system name:

If no name is specified, the generated header file of the C++ wrapper will contain an entry of the form #include Untitled.ifc, which will have to be manually corrected by replacing "Untitled" with the actual system name.

Target Directory

The code that is produced by the IDL compiler is by default placed in the directory in which the compiler was invoked. However, it is possible to control where the output is to be placed by using the switch -T, which takes a target directory as argument:

Limitations

There are some limitations regarding the capability of the IDL compiler. These limitations can be divided into two separate areas: unsupported IDL features and simplifications.

Unsupported IDL Features

The following is a list of IDL features that are not supported in SDL:

Simplifications

The following is a list of simplifications that are made when generating SDL from an IDL specification.


Example 418  : Symbolic name in a constant definition      


Example 419  : Expression Evaluation      

Error Codes

The following error codes may be produced by the IDL compiler:

ERROR 4200 Illegal Option

An illegal options is passed to the IDL compiler (see Flags for a list of available options).

ERROR 4201 IDL feature not supported in SDL

An IDL concept that is not supported by SDT is used (a list of unsupported features is found in Unsupported IDL Features).

ERROR 4203 Could not open file

The IDL compiler attempts to create files to place its output, but for some reason it could not create a file. This is most likely due to an incorrect directory path, but may also be caused by memory limitations.

ERROR 4204 Could not start the IDL compiler

The IDL compiler failed to generate code, probably due to memory limitations.

ERROR 4205 SDL identifier is not unique

This error message will only appear when a local namescope is used.

ERROR 4206 IDL identifier is an SDL keyword

An IDL identifier is used that is also an SDL keyword, which may cause the SDL specification to be illegal.

The Environment

Apart from providing the mapping rules from IDL to SDL, the major part of the integration between SDL applications and CORBA is performed within the environment of the system.

The integration is basically divided into three layers, as is shown in Figure 511, with the SDL system being the topmost one. However, the SDL system itself is always encapsulated by a C++ wrapper (there are different wrappers depending on whether it is the server side or the client side of the application that is viewed). The final layer is the ORB itself, which connects the application with other CORBA applications.

Figure 511  : Architecture of an CORBA application in SDL

Extracted pic [7]

Additionally, a set of environment functions are used between the SDL system and the C++ wrappers to handle signal sending to and from the SDL system.

How all of these layers are connected will be thoroughly explained in the following sections.

The File Structure

There are several files that make up a single application, as is hinted at in Figure 512.

Figure 512  : Creating the files of a CORBA application

Extracted pic [8]

In each layer, a set of files are either predefined or generated, and all of these files are then compiled and linked together to form the final executable.

In all of the following sections a specific IDL file is assumed, say name.idl.

Files Used by the ORB

The ORB creates several files from the IDL file using its own IDL compiler (the files mentioned here are all produced by Orbix; other ORBs have similar files):

Files Used by the C++ Wrapper(s)

Each C++ wrapper is created by the IDL compiler provided by SDT, sdtidl. On the server side of an application the following files would be generated (only when an IDL description is being implemented as an SDL system):

On the client side of an application the following files would be generated (only when an IDL description is used by an SDL system).

Files Used by the SDL System

The SDL system makes use of a runtime library which is defined by the Master Library. When creating a CORBA application, however, it is necessary to add some additional files containing CORBA specific parts (these files are all predefined in the Master Library, and can be found in the directory $sdtdir/INCLUDE/CORBA):

In addition to the files mentioned above, there are several C files generated by the SDL system. This part is further described in The Cadvanced/Cbasic Code Generator.

The SDL System

The first layer of the application is the SDL system itself. The entire application works as a single process in the operative system, and the SDL system part is a single thread of that application. This thread has a scheduler which divides the work between the processes in the system, as is shown in Figure 513.

Figure 513  : The SDL system part of an application

Extracted pic [9]

All requests to and from the SDL system are passed through the environment functions. A call from a client would be inserted through the use of the function xInEnv, while a call to an external server would be passed through the function xOutEnv. This will be further elaborated in Environment Functions.

Also, each process in the SDL system has a corresponding C++ object in the C++ wrapper encapsulating the system. The purpose of the C++ wrappers is described in The Server Wrapper and The Client Wrapper.

The Server Wrapper

The server wrapper is a C++ wrapper that encapsulates an SDL system which implements an IDL description. It also acts as an interface to the ORB, so that all clients wishing to interact with the SDL system must always go through this wrapper. In fact, as seen from the ORB, the C++ object implementation is the SDL system, but the behavior of the objects is actually implemented by the SDL system.

Each process in the SDL system has a corresponding object in the wrapper, and whenever the ORB receives a new request it is routed to a certain object. This object, in turn, converts the request to an appropriate signal or remote procedure call (according to the mapping rules in Operations), which is sent into the SDL system to the corresponding SDL process.

The TIE Approach

The server wrapper's most important feature is the C++ implementation classes (the jargon used in Orbix's Programming Guide is used here as well; other terminologies might be used by other ORBs). Based on the IDL description, a set of IDL C++ classes is generated by the ORB. To these IDL C++ classes it is then necessary to add behavior, which is done by providing C++ implementation classes which are then bound to the appropriate IDL C++ classes using what is known as the TIE approach. This is depicted in Figure 514.

Figure 514  : The TIE approach

Extracted pic [10]

For the C++ classes used here, the IDL to C++ mapping rules that are specified by CORBA are used.

The IDL C++ classes contain the information needed to read and write information from the network, while the C++ implementation classes are supposed to contain the behavior (implementation) of each class.

The objects of these combined TIE classes are the ones that are actually accessed by clients in the distributed CORBA system.

Creating Objects

The same IDL description is used both to create the SDL system skeleton and the C++ server wrapper. This also means that for each process type in the SDL system (that is generated from an IDL description) there exists a corresponding class in the C++ server wrapper.

Whenever a new SDL process instance is created, the function xCreateInstance is called. The purpose of this function is to create a corresponding object of the process instance in the server wrapper, and to set up a communication path between these.

Whenever an object receives a request, this request is forwarded immediately to its corresponding SDL process instance.

Note that process instances that are not derived from an IDL interface have no corresponding C++ object, and cannot be called from external clients.

Terminating Objects

When a process instance is terminated, it depends on the kind of application what happens to the object. If the kernel SCTCORBA was used, the corresponding object is removed, while it is not removed if the kernel SCTCORBASIM is used.

The reason for keeping the object in the latter case is to make it possible to trace client requests in the server even though the actual process instance that was addressed no longer exists. In an application, the signal is simply lost, but an exception is raised to the client that an invalid object reference has been used. This does not show in the server, though.

Note: 

Exceptions that are raised are currently not visible in the SDL system, but could be detected by the C++ wrapper.

Operations and Their Behavior

In a normal CORBA application implemented using C++, the user would have to implement the C++ implementation classes. In this case, however, the C++ implementation classes merely form a kind of gateway to the SDL system, and are generated completely automatically from the IDL description; the user has to provide an implementation of the SDL system instead.

Figure 515 : Handling a request from a client

Extracted pic [11]

An object that receives a request from a client creates the corresponding signal or remote procedure call, and assigns its parameters before it sends it into the SDL system. If the request is not asynchronous a reply is also expected from the SDL system.

In order to be able to handle new requests while one is being treated by the SDL system, each new request is executed in a thread of its own, which means that while one thread is waiting for a reply it is possible for the SDL system to receive requests from other clients as well. Without this threading mechanism, the SDL system would be blocked while handling a request.

The behavior of a general operation can be summarized as follows:

  1. Create a remote procedure call (or signal), assign its parameters from the operation, and send it into the SDL system.
  2. Wait for a reply, and
  3. take the remote procedure reply, assign its parameters to the operation, and return the values to the client.

A more elaborate account of these events are given for different kinds of operations in the next few sections. Note that a new request thread is created for each kind of operation.

Handling Asynchronous Operations

The simplest operation is a oneway operation, which is mapped to a signal in SDL. Once such a request has been sent into the SDL system, the request thread is no longer needed since no reply is expected. The actions that have to be performed in the C++ implementation class are as follows (remember, all of this is automatically generated):

  1. Allocate memory for the signal corresponding to the operation.
  2. If the operation carries any parameters they should be converted from C++ and assigned to the corresponding SDL signal parameters. The conversion functions are generated by sdtidl as part of the server wrapper.
  3. Send the created signal into the SDL system.
  4. Exit the request thread (which is terminated).

Handling Synchronous Operations

For an ordinary operation a reply is always expected (these operations might be thought of as synchronous). Such operations are more difficult to handle than asynchronous operations, especially considering that if only asynchronous requests were made it would not be necessary to spawn a new thread for each request. All ordinary operations are mapped to remote procedures in SDL.

When such an operations is received, the following actions are performed by the C++ implementation class:

  1. Allocate memory for the remote procedure call corresponding to the operation.
  2. If the operation carries any parameters they should be converted from C++ and assigned to the corresponding SDL remote procedure call parameters. The conversion functions are generated by sdtidl as part of the server wrapper.
  3. Send the created remote procedure call into the SDL system.
  4. The request thread is then blocked while the SDL system executes the transition(s) caused by the remote procedure call. It is not awakened until the appropriate remote procedure reply is made.
  5. The remote procedure reply is received, and if it carries any parameters they are converted and assigned to the corresponding C++ operation parameters. These conversion functions are also generated by sdtidl as part of the server wrapper.
  6. If the operation has a return value, it must also be converted and assigned to the operation's return value.
  7. Release the remote procedure reply.
  8. Return any return values to the client, and exit the request thread (which is terminated).

Handling Attributes

An attribute is mapped to two operations, and each of these is handled exactly as an ordinary operation.

Generating the Server Wrapper

The server wrapper is generated automatically from the IDL description at the same time an SDL system skeleton is created (as was described in Converting an IDL Description to an SDL System Skeleton).

It is also possible to generate a server wrapper by addressing the IDL compiler sdtidl directly:

The Client Wrapper

The client wrapper has the same purpose as the server wrapper; it encapsulates the SDL system, and provides an interface to the ORB. A different client wrapper is produced from the IDL description of each server that the SDL system wants to communicate with.

Each operation in the IDL description is associated with a function that is called when the corresponding SDL signal or remote procedure call is made to the environment (i.e., to some object residing outside the SDL system itself). This function executes in a thread of its own, which makes it possible for the rest of the SDL system to continue executing while the request is being handled by a server.

Operations and Their Behavior

In Figure 516 it is shown how a request is associated with a function that describes how a request should be performed. For each operation or attribute in the IDL description there is such a function.

Figure 516  : Handling a request from an SDL system

Extracted pic [12]

The general method for handling a request from a client is as follows:

  1. If no receiver has been specified, locate one.
  2. Take the remote procedure call (or signal), assign its parameters to the corresponding operation, and issue the request to the receiver.
  3. Wait for a reply.
  4. Create a remote procedure reply, assign its parameters from the operation, and send it into the SDL system.

A more elaborate description of these events are given in the next few sections.

Initializing the Client Wrapper

During the initialization of the SDL system, all functions that are associated with IDL descriptions (for external servers) are tied to the corresponding signal definitions in the form of function pointers.

This means that when a signal is received in the function xOutEnv, and it contains such a function pointer, then that function should be invoked as a new thread, which only executes as long as it takes to handle the request. Once the request has been handled, the thread is terminated.

Handling Asynchronous Operations

As was the case in the server wrapper, asynchronous operations are easier to handle than synchronous operations. Such operations are signals that are sent from the SDL system, and they do not require a reply. The function that is called upon the reception of such a request signal from the SDL system has the following behavior:

  1. The signal is received from the SDL system.
  2. If no receiver has been specified, one must be located.
  3. If the signal carries any parameters they should be converted and assigned to the corresponding operation's parameters. The conversion functions needed for this are all generated by sdtidl as part of the client wrapper.
  4. Release the signal.
  5. Issue the request.
  6. Terminate the thread.

Handling Synchronous Operations

When dealing with synchronous operations, which are represented using remote procedures, the reply signal must also be taken into account. In order to be able to continue executing other processes in the SDL system while a request is being handled, each request must execute as a thread of its own. When issuing a synchronous request from the SDL system, the following actions are taken by the request function:

  1. The remote procedure call is received from the SDL system.
  2. If no receiver has been specified, one must be located.
  3. If the remote procedure call carries any parameters they should be converted and assigned to the corresponding operation's parameters. The conversion functions needed for this are all generated by sdtidl as part of the client wrapper.
  4. Release the remote procedure call.
  5. Issue the request.
  6. When the request returns, allocate memory for a remote procedure reply.
  7. If the operation carries any parameters they should be converted and assigned to the remote procedure reply's parameters. The conversion functions needed for this are all generated by sdtidl as part of the client wrapper.
  8. Send the created remote procedure reply into the SDL system.
  9. Terminate the thread.

Handling Attributes

Attributes are mapped to two operations, and each of these is handled exactly as an ordinary operation.

Finding a Receiver

It has been stated several times that if no receiver for a request is specified, one must be located. This is based on the fact that when a request is made in SDL this can be done in one of two ways: with or without a recipient specified using to (as is exemplified in Figure 517).

Figure 517  : Issuing a request in SDL

Extracted pic [13]

If the request is made to a known receiver (as in case B), this PId value in SDL is converted to an object reference in the C++ client wrapper to which a request can be issued.

If no receiver is specified (as in case A), it is absolutely necessary to locate a receiver before a request can actually be made. This is done by making use of the _bind functionality in Orbix (this might be called something else in other ORBs), where a possible recipient object is searched for in other servers.

Generating the Client Wrapper

The client wrapper is generated automatically from the IDL description at the same time an SDL interface package is created (as was described in Converting an IDL Description to an SDL Interface Package).

It is also possible to generate a client wrapper by addressing the IDL compiler sdtidl directly:

Environment Functions

The environment functions make up the glue that binds the SDL system to the C++ wrapper. They are responsible for:

The environment functions also contain much of the actual behavior of the C++ wrappers in the form of functions. This way it is easy to change the underlying implementation without changing the code generated by the IDL compiler.

The files that make up the environment functions are: orb.hh, orbenv.cc, orbutil.hh, and orbutil.cc, and can be found in the directory $sdtdir/INCLUDE/CORBA.

Note: 

Often, the environment functions are placed in a file called sctenv.c, which is part of the Master Library delivery. In the CORBA integration, however, that file is named orbenv.cc.

These files themselves will be examined more closely in The Master Library, whereas their different responsibilities will be covered in this section.

Initialization (xInitEnv)

During the initialization of the SDL system the function xInitEnv is called by the scheduler to allow the environment of the SDL system to be initialized as well.

The main task of xInitEnv is to establish the communication with the ORB. The SDL system cannot be allowed to run before such a connection has been made.

In order to establish the communication, the ORB function impl_is_ready is called using a macro defined in orb.hh:

The server_name is assigned by the server wrapper, and should be the same as is used by the client to _bind to the server (consequently, if the SDL system works only as a client and there is no server wrapper, it is not necessary to establish this connection with the ORB). This name is set by the function xxSetServerName, and if another name is wanted this function call must be altered.

It should also be noted that the second parameter is 0, which means that any pending requests from clients should not be treated during the setup.

Thread Management

As has already been stated, the SDL system executes in a thread of its own. There is also another thread that is always running, and this is the event manager thread, the purpose of which is to listen to the ORB for incoming requests, and to spawn a new request thread whenever a new request is detected.

The event manager thread is created as part of the initialization performed in xInitEnv.

The key functionality in the event manager is the following macro call:

This is a call to the ORB function processEvents, which is responsible for detecting events from external clients. Also note that this call sets an infinite timeout, which means that the thread will never terminate (until the application is closed).

Sending Requests to the SDL System (xInEnv)

The function xInEnv is repeatedly called by the scheduler to check whether there are incoming requests from the ORB that have to be taken care of.

The first thing that is done by this function is to allow all threads that have been started since the last time the function was called to execute, and to place a signal in the InputBuffer. Once this has been done, all the signals in the InputBuffer are sent into the SDL system.

It should be noted that replies from external servers are also placed in the InputBuffer before they are returned to the calling SDL process

Receiving Replies and Issuing Requests (xOutEnv)

When a remote procedure call from the environment is answered by the SDL system, the appropriate remote procedure reply is sent to the environment using the function xOutEnv.

This function is also called if the SDL system issues a (new) request to an external server.

What is done in this function is first to determine if the call was a new request; this is determined by examining if the function pointer Request_Function is set or not. If it is set, that function is called as a new thread, where the actual request to the server is performed.

If the signal was not a new request, it is checked whether it is a remote procedure reply to a previously received remote procedure call. If it is, the reply is entered into the ReplyBuffer, the request thread waiting for that reply is awakened, and then the request thread can get the reply signal from the ReplyBuffer.

If the signal does not fulfill any of these two requirements, it is simply discarded.

Creating a Request Thread (Using Filtering)

For each new request that is received from the ORB (from external clients), a new thread is created by the event manager. The reasons for threading the requests are:

In Orbix, request threads are created by applying a filter to the premarshalling of the request. The filter class appears as follows:

The only thing that is done by this filter is to create a new thread as is shown below. Note that macros are used for all thread functionality.

In the created thread, the request is allowed to continue its ordinary path, and the thread is terminated once the request is done:

Mapping Object References and PId Values

One of the major tasks of the environment function is to keep track of all object references and how they are mapped to PId values. For this purpose a MappingTable is produced, which contains pairs of object references and PId values.

Whenever a new object reference is found, the MappingTable is searched for it. If there already is an entry, it is mapped directly to that PId value, but otherwise it is necessary to create a new PId value which only represents this object reference. The new mapping is also entered into the MappingTable for future references.

PId values always contain a direct reference to their corresponding object reference. The situation is a bit different for objects. For an object corresponding to an SDL process instance, the PId value is known directly by the object, but if the object reference represents an object outside the SDL system, then there is no corresponding SDL process instance. Instead, a PId value with the same appearance as the environment's PId value is created for that object reference, and the only way to find out about this connection is to search the MappingTable.

The Master Library

Some additions has been made to the Master Library to support the CORBA integration of SDL application. The Master Library itself is described in The Master Library, and only the additions will be discussed in this section.

The Master Library

The major addition to the Master Library is that two new library versions are available, SCTCORBA and SCTCORBASIM. All other additions to the Master Library are made only to support these new libraries.

File Structure

The file structure of the Master Library is shown in Figure 518. No changes has been made to this structure, except that the directories SCTCORBA and SCTCORBASIM has been added, and that the INCLUDE directory contains some additional files in the CORBA directory.

There are also some additional files belonging to the CORBA integration, and these can be found in the directory $telelogic/sdt/include/ADT:

Figure 518  : The CORBA libraries

Extracted pic [14]

Library Version Macros

Two new library versions have been added to the Master Library (in the file scttypes.h):

Configuration Macros

A couple of configurations macros have been added:

Thread Macros

Since it is possible to make use of different thread packages, all thread function calls have been replaced by macros which makes it easier to switch between different packages, and also to add additional thread packages if that is needed.

These macros are defined in the file orbutil.hh, which contains definitions for Solaris threads, POSIX threads, and DCE threads.

ORB Function Macros

In order to make it easy to switch to other ORBs, some macros have been defined for calling ORB functions:

These macros are all defined in the file orb.hh.

ORB Binding Macros

Some macros are used to handle the binding between an IDL C++ class and a C++ implementation class. The intention with these macros is to simplify an integration with another ORB:

These macros are all defined in the file orb.hh.

Environment Macros

The environment macros fall within either of two categories: variables or functions. The variable macros are very straightforward, while the function macros are redefinitions of already existing macros. They have been renamed, though, to avoid confusion:

These macros are all defined in the file orb.hh.

The SDL_PId Value

The PId concept has been extended to support object references when the CORBA libraries are used. In the file scttypes.h, the following definitions can be found:

The Object that is pointed at contains both a pointer to the C++ object representing the SDL process instance, and a pointer back the PId value (and is part of the MappingTable).

The makeoptions File

The makeoptions file is used both to create new libraries, and when applications are compiled and linked. This also means that ORB specific information is added to it.

The Definitions Part

The definitions part of the makeoptions file for creating a CORBA application is shown below:

This makeoptions file has the same general structure as the makeoptions files of other libraries, except that ORB specific additions have been made.

Note: 

When using Orbix, the environment variable ORBIX_HOME must be set before it is possible to create CORBA libraries or CORBA applications, and it should be set to the location of the ORB installation.

The Make Rules Part

Aside from the usual definitions of the makeoptions file, the CORBA specific makeoptions file also contains a make rule part:

These rules are used to compile the files that are generated by sdtidl, but also the files generated by the ORB.

Creating a New sctworld.o

Caution! 

Never compile directly in the installation directories! Make copies of the directories instead to avoid corrupting the original files.

In order to create a new kernel, or sctworld.o, for example if any of the Master Library files have been modified, the following steps should be performed:

  1. Set the environment variables $sdtdir and $sctdir to the appropriate directories.
  2. Go to the library that should be updated, i.e., $sctdir.
  3. Use the command make to compile and link all files necessary to build the object file sctworld.o:

  4. make -f $sdtdir/Makefile SDTlib
    

The Make Template File

The make template file is generated by sdtidl whenever a server wrapper is generated, and should be used in the make process when creating a new application. It has the following general structure:

The different parts of this file are as follows:

Servers

When an SDL application works only as a server, i.e., when it does not make any requests to other servers through the ORB, the make template file is automatically created, and the serverOBJECTS part should remain empty.

Servers and Clients

When an SDL application works both as a client and a server, it is necessary to manually add the entries for serverOBJECTS. Each external server needs two entries, as was mentioned above.

Clients

When an SDL application works only as a client, i.e., when it is not possible to make a request to the SDL application, the make template file is not generated, but it is still needed.

It then has to be created and written according to the above description, but objectimplOBJECTS should be left empty. It is necessary to add entries to serverOBJECTS, though.

The sdtsct.knl File

The file sdtsct.knl is described in File sdtsct.knl; it is used to show in the Organizer which kernels that are available.

It is possible to add the CORBA libraries to this file, and suitable entries might be:

Library Name (Kernel) Library Path Comment
CORBA
SCTCORBA

Application with CORBA support

CORBA Debug
SCTCORBASIM

ApplicationDebug with CORBA support

In the make dialog it is then possible to use CORBA and CORBA Debug as standard kernels.


[Previous] [Next] [Contents] [Index]