CTL Manual for Linux/Unix for the Usage with C++ · 1 Introduction The Component Template Library...

39
CTL Manual for Linux/Unix for the Usage with C++ Contents 1 Introduction 4 2 first examples 5 2.1 classes .................................. 5 2.1.1 Interface ............................ 5 2.1.2 Caller .............................. 6 2.1.3 Callee .............................. 6 2.2 Libraries ................................. 7 2.2.1 Interface ............................ 7 2.2.2 Caller .............................. 7 2.2.3 Callee .............................. 8 2.3 basic types ................................ 8 2.3.1 ctl::location ........................... 8 2.3.2 ctl::link ............................. 9 2.3.3 ctl::group ............................ 10 2.3.4 ctl::result<Y> .......................... 10 2.3.5 global functions ......................... 11 2.3.6 CI functions ........................... 11 2.4 nonblocking calls ............................ 12 2.5 template classes ............................. 12 2.5.1 Interface ............................ 12 2.5.2 caller .............................. 13 2.5.3 callee .............................. 13 2.6 template functions ............................ 13 2.7 connecting non matching classes .................... 13 2.7.1 bind constructors ........................ 13 2.7.2 bind methods .......................... 13 2.7.3 bind static methods ....................... 14 2.8 overloading resolution ......................... 14 2.9 Exceptions ................................ 15 3 portable data types 15 3.1 standard types .............................. 16 3.2 stl types ................................. 16 3.3 Type Naming .............................. 16 3.3.1 intrinsic ............................. 16 3.3.2 extrinsic ............................. 16 3.4 the type ctl::any ............................. 17 3.5 user defined types ............................ 17 1

Transcript of CTL Manual for Linux/Unix for the Usage with C++ · 1 Introduction The Component Template Library...

CTL Manual for Linux/Unix for theUsage with C++Contents1 Introduction 4

2 first examples 52.1 classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.1.1 Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.1.2 Caller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.1.3 Callee . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2.2 Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72.2.1 Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72.2.2 Caller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72.2.3 Callee . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.3 basic types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82.3.1 ctl::location . . . . . . . . . . . . . . . . . . . . . . . . . . . 82.3.2 ctl::link . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.3.3 ctl::group . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102.3.4 ctl::result<Y> . . . . . . . . . . . . . . . . . . . . . . . . . . 102.3.5 global functions . . . . . . . . . . . . . . . . . . . . . . . . . 112.3.6 CI functions . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

2.4 nonblocking calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.5 template classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

2.5.1 Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.5.2 caller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.5.3 callee . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2.6 template functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.7 connecting non matching classes . . . . . . . . . . . . . . . . . . . . 13

2.7.1 bind constructors . . . . . . . . . . . . . . . . . . . . . . . . 132.7.2 bind methods . . . . . . . . . . . . . . . . . . . . . . . . . . 132.7.3 bind static methods . . . . . . . . . . . . . . . . . . . . . . . 14

2.8 overloading resolution . . . . . . . . . . . . . . . . . . . . . . . . . 142.9 Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

3 portable data types 153.1 standard types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163.2 stl types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163.3 Type Naming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

3.3.1 intrinsic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163.3.2 extrinsic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

3.4 the type ctl::any . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173.5 user defined types . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

1

3.5.1 intrinsic definition of serialization . . . . . . . . . . . . . . . 183.5.2 extrinsic definition of serialization . . . . . . . . . . . . . . . 193.5.3 polymorph types . . . . . . . . . . . . . . . . . . . . . . . . 19

3.6 cyclic data structures . . . . . . . . . . . . . . . . . . . . . . . . . . 203.7 abstract binary types . . . . . . . . . . . . . . . . . . . . . . . . . . 20

3.7.1 fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . 203.7.2 array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203.7.3 tupel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213.7.4 cstring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223.7.5 reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

4 CI Classes 254.1 CI class as an extrinsic interface . . . . . . . . . . . . . . . . . . . . 25

5 Creation of a service 26

6 Types of Linkage 266.1 lib . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266.2 thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266.3 tcp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276.4 pipe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276.5 pvm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276.6 mpi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276.7 lam . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276.8 daemons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276.9 file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

6.9.1 file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286.9.2 summary of linkage types . . . . . . . . . . . . . . . . . . . 28

6.10 Comparison static linkage versus CTL linkage . . . . . . . . . . . . . 286.11 process groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

6.11.1 client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306.11.2 service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306.11.3 global operators . . . . . . . . . . . . . . . . . . . . . . . . . 316.11.4 termination of asynchron recursions . . . . . . . . . . . . . . 31

7 Life time of CI-object and processes 317.1 life time of processes . . . . . . . . . . . . . . . . . . . . . . . . . . 317.2 life time of objects . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

8 binding of CI’s to processes 328.1 selection by first argument . . . . . . . . . . . . . . . . . . . . . . . 328.2 temporary selection . . . . . . . . . . . . . . . . . . . . . . . . . . . 328.3 local selector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338.4 global selector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

2

9 Usage by other languages 339.1 Usage of the C/Fortran Interface . . . . . . . . . . . . . . . . . . . . 33

9.1.1 Parameter Conversion . . . . . . . . . . . . . . . . . . . . . 349.1.2 Functions for construction, destruction and result handling. . . 34

9.2 Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

10 Security 3610.1 authentification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3610.2 pipes: filtering of stdout . . . . . . . . . . . . . . . . . . . . . . . . . 36

11 Architectural Overview 3611.1 preprocessor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

12 Requirements 3712.1 Compiler Requirements . . . . . . . . . . . . . . . . . . . . . . . . . 3712.2 Communication Channel Dependencies . . . . . . . . . . . . . . . . 37

13 Grammatic of the Component Interface 38

3

1 IntroductionThe Component Template Library (CTL) is an implementation of the component tech-nology based on C++ generic template programing \cite{tplcpp}. Similar to CORBA\cite{CORBA} it can be used to realize distributed component-based software systems,where a component is a piece of software which consists of a well defined interface andan implementation. Interface and implementation are connected throw a communica-tion channel, e.g. TCP/IP or MPI. In this way the usage of a component is independendof their location, meaning that the component is network transparent.

One important feature of the CTL is their lightweight design and their seamlessintegration into the C++ language. It is a template library and in its simplest configu-ration it depends on nothing than the standard libraries which are available on nearlyall Unix plattforms. Like the standard template library (STL) — which is a part of theC++ language — provides generic container datatypes, the CTL provides methods torealize distributed systems.

The CTL can be used for fast prototyping of distributed software systems. Butits main focus is to transform existing C/C++ or FORTRAN libraries to remote ac-cessable software components. The idea behind the CTL is to provide a mechanismwhich makes the development of distributed systems as easy as possible, so that thedifferences between traditional monolithic programs and complex distributed softwaresystems nearly vanish.

Main design aspects were:

• easy syntax (using overloading)

• header only (no precompile or install)

• independance of other libraries (needs only sockets, dlopen, pthreads (mpi/pvmcan be used optionally)

• expandable for other communication protocols (open communication interfaceand protocol)

• maximal decoupling of components (using idl, abstract types)

• covering the parallel and the distributed programming models (group and links)

• direct process to process communication (no daemon in between)

• uniform behaviour of remote (tcp/ip, mpi, pvm, pipes, daemons) and local (li-brary, thread) linkage types

• extrinsic usage of user defined types

• support of user defined types

• open for new communication protocols

4

The main idea (as Com, Corba, ...) is to define an interface description of a library thatgives all informations two components must share in order to understand each otherin a type safe way. This information includes the names and signatures of functions,classes and their methods. In this context the signature of a function, method, staticmethod or constructor specifies its name, the argument list, the type of the result aswell as the types of exceptions which might be thrown.

2 first examplesAny dual interactions have three parts: the participating components and the couplingbetween them. Therefore the examples have to handle the component interface, thecaller and the callee side.

2.1 classesA CI interface may contain class definitions.

2.1.1 Interface

A CI class definition might look like the following example.

#ifndef _1ST_CI_

#define _1ST_CI_

#include ctl.h

#define CTL_Class firstClass

#include CTL_ClassBegin

# define CTL_Constructor1 (const string /*initfile*/), 1

# define CTL_Method1 int4, f, (const real8) const, 1

# define CTL_Method2 void, g, (real8, const bool), 2

# define CTL_StaticMethod1 bool, s, (), 0

#include CTL_ClassEnd

#endif

The C++ notation of this class is

class firstClass

{

public:

firstClass(const string /*initfile*/&);

5

int4 f(const real8&) const;

void g(real8, const bool);

static bool s();

};

The CTL interface description is defined in terms of C-macro definitions which areexpanded to the functions which perform the data serialisation and transport. Due tothe fact, that the C-preprocessor can not count lists, at the end of each declaration thenumber of arguments must be given.

2.1.2 Caller

#include firstCI.h

int main()

{

firstClass::use(�host:/usr/peter/comp/libsecondImpl.exe tcp�);

firstClass C(�initfile�);

int n=3;

double x=3.3;

std::cout<�<C.f(x)<�<std::endl;

C.g(x, true);

std::cout<�<x<�<std::endl;

std::cout<�<firstClass::s()<�<std::endl;

}

2.1.3 Callee

#define CTL_Connect

#include �firstCI.h�

#include <string>

class firstImpl

{

public:

firstImpl(const std::string &fileName)

{ std::cout<�<filename<�<std::endl; }

int f(double x) const

{ return int(x)+1;}

6

void g(double &x, bool sw)

{

if(sw)

x = 0;

}

static bool s()

{ return true; }

};

void CTL_connect()

{

ctl::connect<firstClass, firstImpl>();

}

2.2 LibrariesA CI library may contain CI class definitions and CI function declarations.

2.2.1 Interface

#ifndef _2nd_CI_

#define _2nd_CI_

#include ctl.h

#define CTL_Library secondCI

#include CTL_LibBegin

# define CTL_Function1 int4, f, (const real8), 1

# define CTL_Function2 void, g, (real8, const bool), 2

#include CTL_LibEnd

#endif

2.2.2 Caller

#include secondCI.h

int main()

{

secondCI::use(�/usr/peter/comp/secondImpl.so thread�);

int n=3;

double x=3.3;

std::cout<�<secondCI::f(x)<�<std::endl;

7

secondCI::g(x, true);

std::cout<�<x<�<std::endl;

}

2.2.3 Callee

#define CTL_Connect

#include �secondCI.h�

int4 f(real8 x)

{ return int(x)+1;}

void g(real8 &x, bool sw)

{ if(sw)

x = 0;

}

void CTL_connect()

{

secondCI::connect(&secondCI::f, &f);

secondCI::connect(&secondCI::g, &g);

}

2.3 basic types2.3.1 ctl::location

class location

{

void setTerminal (const std::string &trm);

//assign a terminal.

void setDebug (const std::string &dbg);

//assign a debugger.

location (const char *locC, linkage =undefined);

location (const std::string &locStr, linkage =undefined)

//Constructor accepting a string in ssh syntax.

location (const std::string &e, const std::string &p, const std::string &h=std::string(), linkage =tcp)

//constructor assigning the executable, the path, and optionally the host (default localhost) and the linkage (default tcp).

};

modifiers for location:

• -l <linkage> in {lib,thread, tcp, ssl, pipe, lam, mpi, pwm, dmn,...}

8

• -f <logfile> (absolut or relative to current working directory of destination com-ponent)

• -d <working directory> (absolut or relative to executable)

• -v be verbose

• -p logical id in group (default=-1)

• -S size of group (default=0)

• -h hostname/IP of client

• -x <terminal> run in terminal (default = xterm -e)

• -g <debugger> start in debugger, implies -x (default = gdb)

• -s <remote shell> at <port> (defaults = ssh at 22)

• -n <value> set priority (default value = 1) decrement process priority by value

• -L <port> use as local port

• -R <port> use as remote port

• -c cypher messages

2.3.2 ctl::link

class link

{

link ()

// no ressource allocation.

link (const ctl::any &property)

//Takes a property for the location selector.

link (const std::string &loc, linkage typ=undefined)

//if the linkage is file loc is interpreted as an filename, otherwise as a location in ssh syntax.

link (const location &loc, linkage typ=undefined)

//create a link using the given location and the specified linkage.

bool operator! () const

// check wether the link is still valid.

int test() const;

// return size of data available, -1 otherwise

template<class T> const link &operator<�<(const T&) const;

template<class T> const link &operator>�>(T&) const;

// send/recv object of type T

};

9

2.3.3 ctl::group

class group

{

template<class LocVec> group (const LocVec &, linkage)

// create a group by the sample of location 's and the given linkage.

group (int n, const char *const *arg, const char *logFile=0, bool cwd=false, bool enableDmn=false)

// create a group by the command line arguments, logFile if given will define the the log file(s), if cwd is set the working dir is set corresponding to arg[0].

bool operator! () const;

// check whether the group is still valid.

bool run () const

// blocking:run a distributed application until termination is detected.

link operator[] (int p) const

// return the specified link of this group.

int size () const

// return the size of this group.

int logId () const

// returns the logical Id of this instance of the group.

template<class T> T globalSum (const T &t) const;

template<class T> T globalProd (const T &t) const;

template<class T> T globalMin (const T &t) const;

template<class T> T globalMax (const T &t) const;

// blocking: compute the sum, prod, min, max of t over all processes in this group.

};

2.3.4 ctl::result<Y>

template<class Y> class result

{

result (const result< Y > &)

// implements the owner concept as std::auto_ptr.

result<Y>& operator= (const result< Y > &)

// implements the owner concept as the std::auto_ptr.

bool operator! () const

// check whether result is available.

operator const Y& () const

10

// blocking: return the returned value.

// update all non const arguments of former call

};

2.3.5 global functions

set the Locator for implicit location selection

template<class locSlct>

void ctl::setLocator(const locSlct&);

enable polymorphic IO of Type

ctl::connect<Type>();

// user defined

void CTL_connect();

2.3.6 CI functions

A library or class interface has together with the function declared in the interface thefollowing static functions:

CI::connect<Impl, Detail = void>();

CLib::connect<CIfunc, Implfunc>(CIfunc*, Implfunc*);

CLib::connect<FID, Implfunc>(Implfunc*);

ctl::link &CLib::use(const ctl::link & =ctl::link());

ctl::link &CI::use(const ctl::link & =ctl::link());

A CI class has additionally to constructors declared in the interface the template con-structor

template<class Impl> CI::CI(const Impl &, ctl::channel=ctl::serial);

where Impl must be a valid implementation of CI, that meens Impl defines all con-structors, methods and static methods declared in the interface in a way that the over-loading rules given in section <overloading> are sucessfully applied. So a CI classcan be implemented locally and acts therefor here as an extrinsic interface class (a g++class signature).

11

2.4 nonblocking callsexample: receive result in blocking way

// blocking call

int n = firstCI::f(x);

receive result in non blocking way

// non blocking call

ctl::result<int4> res = firstCI::f(x);

while(!res)

{

// do other stuff

}

int n = res;

receive a couple of results in non blocking way

vector<double> task;

vector<int> result;

vector<firstCI> worker(nWorker);

// instantiate worker

vector<int> state(worker.size(), -1);

vector<ctl::result<int> > resHandle(worker.size());

int read = 0, curr = 0;

while(read<task.size())

{

for(int p=0; p<worker.size(); p++)

{

if(state[p]>=0 && !!resHandle[p])

{

read++;

result[state[p] ] = resHandle[p];

state[p] = -1;

}

if(curr<task.size() && state[p]<0)

{

state[p] = curr;

resHandle[p] = worker[p].f(task[curr++]);

)

}

}

2.5 template classes2.5.1 Interface

# define CTL_ClassTmpl sorterCI, (S,T), 2

12

# include CTL_ClassBegin

# define CTL_StaticMethod void, sort, (array<S>), 1

#include CTL_ClassEnd

defines a class template with the type parameters S and T as

template<class S, class T> class sorterCI

Inside the class body S and T are valid type identifier.

2.5.2 caller

sorterCI<double, int> sorter(link);

std::list<double> val;

sorter.sort(val);

2.5.3 callee

ctl::connect<sorterCI<double, int>,myDoubleSort>();

ctl::connect<sorterCI<int, char>, myIntSort>();

2.6 template functionsThe declaration corresponds to

# define CTL_FunctionTmpl1 void, (h, (S,T), 2), (const S ,T), 2

corresponds to

template<class S, class T> void h(const S&, T&);

2.7 connecting non matching classesIn the case an CI class has to be implemented by an existing library more often themethod names will not match.

In another case explicite overload resolution might be necassary. For this purposesone may define a structure with the meaning of a connection detail and give it as a typeparameter to the class connector.

2.7.1 bind constructors

CTL_Constructor(cid,(args),#args)

2.7.2 bind methods

CTL_Method(mid, y, meth,(args),#args)

13

2.7.3 bind static methods

CTL_StaticMethod(fid, y, func,(args),#args)

Example:

struct connectDetail

{

CTL_Constructor(1, (const std::string &), 1);

CTL_StaticMethod(1, int, ParticleImpl::h, (std::vector<double>&, double), 2);

CTL_Method(2, float, ParticleImpl::f, (std::vector<int>, float), 2);

};

void CTL_connect()

{ // connect classes

ctl::connect<TracerCI,ParticleImpl,connectDetail>();

}

Remarks:

1. The name of connect detail class is user defined and therefore arbitrary:

2. The connect detail parameter has only effect to the constructors, static and nonstatic methods explicitly given in that connect detail

3. A static method can be connected to an arbitrary global function (this includespublic static methods of arbitrary classes)

2.8 overloading resolutionThe following overloading resolution rules are applied in the given sequence.

• If a constructor, method, or static method is connected explicitly, the connectedone will be called (a gobal function or function template must be connectedexplicitly via CI::connect() ).

• If the argument list contains no abstract type, the usual C++ overloading rulesare valid.

• If the argument list contains at least one abstract type, the method or staticmethod of the implementation class with the name given in the interface is cho-sen. Overloading is in this case not possible.

These rules imply that a constructor with an abstract argument must be connected ex-plicitly using CTL_Constructor.

14

2.9 ExceptionsAny CI-method, constructor or function may throw an exception. In order to catch suchan exception on the client side the types of exceptions which might be thrown must begiven in te Interface-Declaration.

Example

#define CTL_Class firstClass

...

# define CTL_Method1 int4, f, (const real8) const, 1

# define CTL_Method1Throws (std::string, ctl::exception),2

...

client:

firstClass c1;

try {

int i = c1.f(3.1416);

}

catch(const std::string &)

{ ... }

catch(const ctl::exception &)

{ ... }

catch(...)

{ ... }

or

ctl::result<int> r=c1.f(3.1416);// nothing to catch here

while(!r) { // nothing to catch here

// do other stuff

}

try{ // catch exception where the result is casted

int i=r;

}

catch(const std::string &)

{ ... }

catch(const ctl::exception &)

{ ... }

catch(...)

{ ... }

3 portable data typesDatatypes which appear in CTL interfaces must be transportable over a network. Thissection explains the basic datatypes which are already prepared to work with the CTLand describes how to serialize user defined datatypes.

15

3.1 standard types

3.2 stl typesInstantiations of the stl template types:

vector<T, allocator>, queue<T, allocator>, list<T, allocator>, set<T, compare, allo-cator>,

pair<key, val>, complex<value_type>, map<key, value, compare, allocator>,basic_string<T, allocator> are portablewith portable T, key and value are portable if T, key and value are portable.

3.3 Type NamingIn order to serialze types which are polymorph, some type identification is needed,see sections <any> , <polymorph io> and <references> Herefor the typeinfo.name()function could be used if it would give the same name for each C++-Compiler, what isnot the case. Therefor the CTL introduces it’s own type naming

3.3.1 intrinsic

These macros can be used inside a class/ template class definitions.

CTL_TypeName(T)

CTL_TemplateName(T, (X1, X2,...,Xn), n)

3.3.2 extrinsic

These macros can be used in the global namespace.

CTL_SetTypeName(T)

CTL_SetTemplateName(T, (X1, X2,...,Xn), n)

Examples:

namespace wire

{

class AlgorithmBase

{

public:

virtual CTL_TypeName(wire::AlgorithmBase);

};

template<class T> class Algorithm : public AlgorithmBase

{

public:

CTL_TemplateName(wire::Algorithm, (T), 1);

};

} // wire

// or alternativly without virtual call mechanism

CTL_SetTemplateName(wire::Algorithm, (T), 1);

16

Assigns AlgorithmBase the type name “wire::AlgorithmBase” and Algorithm<char*>the name “wire::Algorithm<char*>”, where the typename of AlgorithmBase will beextracted using the virtual method call mechanism. In the following we say a type isnamed iff there is a CTL name definition for this type. All standard types and the typeslisted in section <stl::types> are named.

.

3.4 the type ctl::anyIn order to implement generic algorithms working with objects of arbitrary non uniformtypes an implementation of an any type is useful. The type any has a constructorexcepting an object x arbitrary type X. The conversion of an any to a Y* gives a validpointer of type Y iff Y is X or derived by X. The type any implements a value semanticbased on the late copy mechanism. The any object is successfull transportable iff X istransportable, named and connected.

If one link reads the any object where X is not named and connected or X is evennot defined the readed any object will carry only the binary data representation of x.It may be send to further processes, which iff X is there transportable, named andconnected may sucessfully perform the recast to X*.

class any

{

// construction

any();

template<class T> any (const T &t);

any(const any &obj);

// assignment

template<class T> any &operator= (const T &t);

any &operator = (const any &obj);

template<class T> operator T*();

// conversion

template<class T> operator const T*() const;

void clear();

bool operator !() const;

};

3.5 user defined typesA datatype or class which might be used in a CTL interface as an argument or returntype must be transportable. The basic datatypes which comes with the CTL (see section\ref{sec::datatypes}) as well as the basic stl container types are already prepared tobe transportable. Transportable does mean, that the object can be serialized into adatastream in ordr to send it over a communication channel. If one wants to use userdefined datatypes or classes inside methods or functions of a CTL interface, one haveto serialize the class. Therefore the CTL provides a macro called CTL_Type.

17

namespace wire

{

class Data

{ public:

std::string _host;

std::string _path;

std::string _service;

std::string _user;

std::string _password;

int _count;

double _time;

Data(){}

~Data(){}

CTL_Type(wire::Data, tupel,(_host,_path,_service,_user,_password,_count,_time), 7)

}

template<class T> class Vector

{

void resize(int);

T *begin();

T *end();

CTL_Template(wire::Vector, isArray, (begin, end, size, resize),4, (T), 1)

};

};

3.5.1 intrinsic definition of serialization

Put into the (template) class body a

CTL_Type/CTL_Template

or

ctl::oStream &write(ctl::oStream &os) const

{ ... }

ctl::iStream &read(ctl::iStream &is)

{ ... }

Remarks:It’s not a good idea to have virtual read/write methods, because the consistancy of

the interpretation of the binary stream between writer and reader will most likely bedestroyed, see Section <polymorph types> how to realize polymorph IO.

18

3.5.2 extrinsic definition of serialization

Put into the global namespace:CTL_SetType/CTL_SetTemplateor write

namespace ctl

{

oStream &write(oStream &os,const T &t)

{

// write attributes of T in some order

...

}

iStream &read(iStream &is,T &t)

{

// read attributes of T in the same!! order

...

}

}

Remark: Beware carefully the consistancy/symmetry of the write and read functionsotherwise the stream interpreation at the reading side will be corrupted and systembehavior becomes undefined.

The expansions of the macros CTL_Type/CTL_Template or CTL_SetType/CTL_SetTemplatemakes the target types portable and named.

3.5.3 polymorph types

Portable and virtual named classes are polymorph transportable via the any type andarbitrary reference types (including pointer), see section <reference types>.

Example:sender

ctl::link p;

wire::algorithmBase *alg=new wire::Algorithm<char*>;

p<�<alg;

reader

ctl::connect<wire::algorithm<char*> >();

wire::algorithmBase *alg=0;

p>�>alg;

On the readers side alg will now be a pointer to an wire::Algorithm<char*> which is acopy of the object allocated by new wire::Algorithm<char*> on the sending side.

In order to make the defined type name available to the reader the functionctl::connect<T>() must be called before reading is done.

19

3.6 cyclic data structuresIf the edges of a graph data structure are written/read via references this structure mayalso be cyclic. Cycles are resolved by the serialisation mechanism of the CTL, see also<reference>.

3.7 abstract binary typesIf two components have to exchange structured data types without sharing any datatype declaration an abstraction concerning binary representation is needed. The meanideas are

• any structured type is a composition of simpler types

• there are only a few compositions

• to read a structured data only its binary representation is needed

3.7.1 fundamentals

The fundamental types defined in the CTL are:the integral types

bool with values in {0,1}

char=int1, int2, int4, int8

unsigned char =uchar=uint1, uint2, uint4, uint8

and the float types

real4, real8

where each postfix number tells the number of bytes (=sizeof) in the binary represen-tation.

3.7.2 array

template<class T, int level=1> class array;

serialisation as

os<�<int8(vec.size());

for(int8 i=0; i<vec.size; i++)

os<�<vec[i];

examples

std::vector<T>

std::set<T>

std::list<T>

std::queue<T>

20

3.7.3 tupel

template<class T0, class T1=empty,..., class Tmax=empty> class tupel;

T0 t0;

T1 t1;

...

Tn tn;

(n<max)

os<�<t0<�<t1<�<...<�<tn;

examples

std::complex<T> -- tupel<T,T>

std::pair<S,T> -- tupel<S,T>

struct info

{

int n;

float x,y;

CTL_Type(info, tupel, (n,x,y), 3

};

-- tupel<int,float,float>

map<key, val> = array<tupel<key, val> >

Example sparse matrixThe following class defines two constructors accepting a sparse matrix in the ijv

and in the row by row formats.The ijv format is an array of entries of the form (i,j, value) which has the binary

representation:

array<tupel<int4, int4, real8> >

The row by row format is an array of rows, where each row has an row index and avector of entries of the form (j, val). Its representation is

array<tupel<int4, array<tupel<int4, real8> > > >

Due to restrictions of the preprocessor a type specifier in a CI may not contain a un-braced comma, therefor this types must be rewritten in the modified list syntax as

array<(tupel, (int4, int4, real8), 3)>

and

array<(tupel,(int4, (array, (tupel,(int4, real8), 2) , 1) ), 2)>

This leads to the interface

21

#define CTL_Class sparse_solverCI

#include CTL_ClassBegin

# define CTL_Constructor1 (const array<(tupel, (int4, int4, real8), 3)> /*ijv-matrix*/), 1

# define CTL_Constructor2 (const array<(tupel,(int4, (array, (tupel,(int4, real8), 2) , 1) ), 2)>) /*row-by-row-matrix*/), 1

# define CTL_Method1 bool, solve, (array<real8> /*x*/) const, 1

#include CTL_ClassEnd

Remark: If the interface will only be used by C++ one can just use typedefslike

typedef tupel<int4,int4, real8> ijv_item;

typedef tupel<int4,real8> jv_item;

typedef tupel<int4,array<jv_item> > row;

Caller and Callee can use their own representations for example

typedef std::pair<int,double> jv_item;

typedef std::pair<int,std::vector<jv_item> > row;

typedef std::vector<row> row_by_row_matrix;

row_by_row_matrix A;

std::vector<double> x;

sparse_solverCI S(A);

S.solve(x)

3.7.4 cstring

template<class T> class cstring;

while(!!str[i])

os<�<str[i++];

os<�<T();

examples

char *

std::string

3.7.5 reference

template<class T> class reference;

if(!t)

return os <�< true <�< int4(-1);

22

int4 logAddr = os.getStreamId(t);

if(logAddr>0) // t is already in the stream

return os <�< true <�< logAddr;

os.addReference(t);

os<�<false;

const char *typeName=ctl::typeName<T>(*t);

if(!typeName)

return os<�<std::string();

os <�< std::string(typeName)<�< binarySize(*t) <�< *t;

examples

std::auto_ptr<T>

T*

remarks:If in the serialisation of a argument list references to the same object occurs more

than once, the object will be placed only once into the stream.If on the reading side the exact type is connected (by calling ctl::connect<T>() ) the

object can be read via a reference to an arbitrary base type of T.Example:

Implementation

#include <ci/graph.ci>

#ifndef _GRAPHNODE_H_

#define _GRAPHNODE_H_

class graphNode {

public:

typedef graphNode* pointerT;

private:

typedef std::list<pointerT> neighborT;

neighborT neighborM;

virtual void printPriv(std::ostream&) const {}

// used to resolve cycles mutable

bool visitedM;

void reset() const

{

if(visitedM) {

visitedM = false;

for(neighborT::const_iterator nb=neighborM.begin(); nb != neighborM.end(); nb++)

if(!!*nb)

(*nb)->reset();

}

}

public:

CTL_Type(graphNode, tupel, (neighborM), 1);

23

graphNode(): visitedM(false) {}

virtual ~graphNode() {}

void addNeighbor(const pointerT &node) {

neighborM.push_back(node);

}

void print(std::ostream &os, bool first = true) const {

if(!visitedM)

{

visitedM = true;

printPriv(os);

for(neighborT::const_iterator nb=neighborM.begin(); nb != neighborM.end(); nb++)

if(!!*nb)

(*nb)->print(os, false);

if(first) // reset to non-visited

reset();

}

}

};

class nodeTypeA: public graphNode {

double valueM ;

void printPriv(std::ostream& os) const {

os < < "nodeTypeA { value = " < <valueM<�< "}\n";

}

public:

nodeTypeA(double value =0): valueM(value) {}

CTL_Type(nodeTypeA, tupel, ((graphNode&)(* this), valueM), 2);

};

class nodeTypeB: public graphNode {

int iM, jM;

void printPriv(std::ostream& os) const {

os < < "node- TypeB { i = " < <iM< < ", j = "< <jM< <"}\n";

}

public: nodeTypeB(int i =0, int j =0): iM(i), jM(j) {}

CTL_Type(nodeTypeB, tupel, ((graphNode&)(* this), iM, jM), 3);

};

#endif

CI

#ifndef _GRAPH_CI_

#define _GRAPH_CI_

#include <ctl.h>

class graphNode;

#define CTL_Library graph

#include CTL_LibBegin

# define CTL_Function1 bool, set- Graph, (const reference<graphNode>), 1

24

#include CTL_LibEnd

#endif

Connect

#define CTL_Connect

#include <ci/graph.ci>

#include <graphnode.h>

bool setGraph(graphNode* node) {

node->print(std::cout);

return true;

}

void CTL_connect() {

ctl::connect<nodeTypeA>();

ctl::connect<nodeTypeB>();

graph::connectID<1>(setGraph);

}

Client

void callGraph() {

graphNode::pointerT A,B,C,D;

A = new nodeTypeA(3.14);

B = new nodeTypeA(2.71);

C = new nodeTypeB(3,4);

D = new nodeTypeB(7,1);

// build a graph containing cycles (A->A), (A->B- >C->D->A)

A->addNeighbor(A); A->addNeighbor(B); A->addNeighbor(D);

B->addNeighbor(C); B->addNeighbor(C); B->addNeighbor(D);

C->addNeighbor(B); C->addNeighbor(D); C->addNeighbor(0);

D->addNeighbor(A); D->addNeighbor(C);

A->print(std::cout);

ctl::connect<nodeTypeA>(); ctl::connect<nodeTypeB>();

graph::use("../../graph/linux/graph.exe - l tcp");

graph::setGraph(A);

}

4 CI ClassesCI classes are named and portable.

4.1 CI class as an extrinsic interfaceThe g++ Compiler supports te so-called signature concept. This concept is also rep-resented in the CTL, If a class Impl implements all constructors, method and staticmethods given in an Interface CI then

25

Impl impl;

CI ci(impl);

instantiates a CI class which implementation is given by the Impl impl. The object ciwill hold a copy of impl, which will be got by the Impl copy constructor.

5 Creation of a servicemakefile using g++ on a linux system

CC = g++

CTL = $(CTL_PATH)/ctl/include

CI = $(CI_PATH)

LIBS = -limpl.a

CFLGS = -I($CTL) -I$(CI)

service.exe: connect.o makefile

$(CC) --shared connect.o $(CLIBS) -o service.so

$(CC) connect.o $(CLIBS) -o service.exe

connect.o: connect.cpp makefile

$(CC) -c $(CFLGS) connect.cpp -o connect.o

6 Types of LinkageThe component technology implemented by the CTL can be seen as an generalisationof dynamic linkage to a runtime linkage with different link mechanisms.

For each linkage type the same following syntax is valid

ctl:location loc(�user@host:path/exec [linkage]�);

ctl::link P(loc, [linkage]);

As the service for the cases lib and thread a shared object service.so is needed. Theother linkage types need an executable like service.exe.

6.1 libBehaviour like classical static linkage. In the time frame of the caller the result isimmediatly available.

6.2 threadStart in a seperate thread each function or method invocation. The link creates onethread for execution. Subsequently called functions will be queued.

26

6.3 tcpuse sockets for communication

The connections are buildt up in the following steps

• the client spawns service by [ssh ] service.exe tcp:host:port:logID:nprocs andinvokes accept(port)

• the service invokes connect(host) to establish the connection

6.4 pipethe client invokes service by

[ssh] service > inpipe < outpipewhere inpipe and outpipe are cretaed by the client.Note: this mechanism works also through a firewall if ssh can.

6.5 pvmassumes te compile flag CTL_PVM

uses pvm as for communication

6.6 mpiassumes te compile flag CTL_MPI

uses mpi for communication

6.7 lamlike mpi but assumes the lam mpi-version for dynamic process allocation

6.8 daemonsuses sockets for communication

start a service optionally telling him a port to listen

service.exe [port]

If no port is given the service will use aq free random port number. Now the servicewill wait for connection using the given or random port number.

Any process can create a link to this service by

link daemon(�host:port�, ctl::dmn);

If not denied by a firewall the service will accept a connection to the client.This connection exists as long as the link at the clients side.

27

6.9 filelink str( filename mode , file)

Remark the cases thread, tcp, pvm, mpi, lam, daemons have all the same behaviourconcerning result availability.

6.9.1 file

6.9.2 summary of linkage types

The following table gives an overview of the supported linkage types.channel used tools communication via: creation via:. connection via:

lib libdl function call dlopen dlsymthread libpthread function call dlopen+pthread_create dlsym

tcp sockets+ssh tcp/ip [ssh] spawn accept:connectpipe pipes+ssh stdin/stdout [ssh]spawn pipesmpi mpich/lammpi MPI_Ibsend/MPI_Recv [ssh] mpirun MPI_Initlam lammpi MPI_Ibsend/MPI_Recv MPI_Comm_spawn MPI_Initpvm pvm pvm_send/pvm_recv pvm_spawn pvmdmn sockets tcp/ip — connect:acceptfile stdio fwrite/fread — fopen

channel location local remote grouplib path/lib yes no no

thread path/lib yes no nyitcp user@host:path/exe yes yes dynamic

pipe user@host:path/exe yes yes nompi host:path/exe yes yes static + extrinsiclam host:path/exe yes yes dynamicpvm host:path/exe yes yes dynamicdmn host:port yes yes nofile filename yes no no

6.10 Comparison static linkage versus CTL linkagesource editing level

• include class definitions and function declarations

• call constructor, method or function

linkage level

• search for symbol in list of objects and libraries

• link against unique match

run time

28

• write function parameter onto stack

• read function parameter from stack and evaluate functionbody

One main concept of the CTL is a generalisation of linkage.In the monolithic case an application is build up by the linker from a list of objects

and dynamic or static libraries. For each called function the compiler wants to seeits declaration. After compiling the linker first looks in the given list of objects andlibraries for an definition of the called function (using it’s signature as an identifier) andthen binds the call to exactly one implementation. In a list of objects such a definitionmay occur only once (otherwise multiple definition), in a list of libraries the first foundimlementation will be taken. If no definition was found, the error ”undefined symbol”occures.

In this case all listed objects and libraries must be available at linkage time onthe compiling machine. Furthermore the set of used implementations is determinedalready at linkage time. While run time this implementation will be executed on thesame processor in the same process as the calling function.

modul.cc

modul.a/so

modul.h

direct callrun time

compiling

#include

linking

application.cc

application.o

application.exe

The Windows registry and the Unix/Linux dlopen mechanisms enable run timelinkage. But also here only one implementation of a function can be used, the executionis still performed on the same processor and in the same process.

The CTL gives both, the selection of an implementation and the binding, in usershand. At run time it can (and must) be selected which implementation on which hostto be linked in which mode. In the definition of the library (in this context calledcomponent) the binding of the function signature to an implementation must be given.

29

modul.ci

run time

compiling

#include

linking

modul.cc

modul.a/so

bind_modul.cc

bind_modul.o

libmodul.so

libmodul.exe

direct call

communicationapplication.exe

application.o

application.cc

modul.h

In the following CI is used as short cut for Component Interface.

6.11 process groupsThe class ctl::group implements the Single program multiple data (SPMD) and theSingle program multiple data MPMD programming models.

6.11.1 client

container<location> locations container in { std::vector, std::list, std::set, ctl::vector }

group(locations, ctl::linkage)

constructor creates complete graph of the processes defined by the locations.Location from { pvm,lam, tcp }The creating process get’s in the group the logId 0.

std::list<ctl::location> list;

list.push_back("../../group/linux/group"); list.push_back("../../group/linux/group"); list.push_back("../../group/linux/group");

ctl::group G(list, ctl::tcp);

int num = 100;

int sum = G.globalSum(num);

6.11.2 service

group(int argc, const char *const * argv, const char *logFile, bool cwd)

example

30

#include <ctl.h>

int main(int argc, char ** argv)

{

ctl::group G(argc, argv);

int me = G.logId(), nProcs = G.size();

int sum = G.globalSum(me);

printf("me = %d sum = %d\n",me, sum );

if(nProcs > 2 && me==1)

{

double x = 3.1416;

G[2]<�<x;

}

if(nProcs > 2 && me==2)

{

double x;

G[1]>�>x;

printf("got x = %e\n",x);

}

return 0;

}

call by mpirun -np 4 group mpi ot by clientor by other code via

6.11.3 global operators

global assoziative operations are performed in the hypercube topology, see ???{add, mult, min, max, sample, {udf}}

6.11.4 termination of asynchron recursions

group::run starts a termination algorithm see Mattern.

7 Life time of CI-object and processes

7.1 life time of processesThe life time of processes is defined via ownership.

The creating process is the owner. The child process will terminate, when thereferencing group or link is destroyed. This is the case at the latest when the ownerterminates.

31

7.2 life time of objectsThe life time of objects is defined via reference counting using the credit method, seeMattern. If the last reference is destroyed the object will be destroyed. This needone remote method invocation at the time the last reference inside one process to anCI-Class is destroyed.

8 binding of CI’s to processesIn the order of priority the following four mechanisms for binding a function, construc-tor or static method call to a link exist.

8.1 selection by first argumentTo any global function, constructor or static method of a CI, the destination link can beoptionally given as the first argument

int main()

{

// as before

firstClass C(firstProc, �initfile�);

std::cout<�<C.f(x)<�<std::endl;

std::cout<�<firstCI::f(firstProc, x)<�<std::endl;

}

Remarks:A link is not portable and may not be an argument in the CI definition. Therefore

overloading ambiguity will not arize.Non static methods do not accept a link as the first argument. The destination link

is here determined by the corresponding CI class object.

8.2 temporary selectionint main()

{

ctl::location loc(�host:/usr/peter/comp/firstImpl.exe tcp�);

ctl::link p(loc);

firstCI::use(p);

firstClass C(�initfile�);

firstCI::use();

}

see also <global functions> : use

32

8.3 local selectorDefine a locator by

ctl::location my_locator(const std::string &id, const ctl::any &property);

or

class my_locatorType

{

...

ctl::location operator() (const std::string &id, const ctl::any &property);

} my_selector;

and give it to the ctl environment by

int main()

{

ctl::setLocator(my_locator);

firstClass C(�initfile�);

std::cout<�<C.f(x)<�<std::endl;

}

8.4 global selectorbash > export MY_LOCATOR=”/usr/peter/comp/my_selector.so lib”

Compile with the define likeg++ -DCTL_LOCATE=MY_LOCATOR appl.cc

int main()

{

// just use firstClass

firstClass C(�initfile�);

std::cout<�<C.f(x)<�<std::endl;

}

9 Usage by other languages

9.1 Usage of the C/Fortran InterfaceThe CTL provides language bindings for C and FORTRAN, eg. it is possible to trans-form an existing FORTRAN library into a remote accessible software component andto use a CTL component by Fortran applications. Especially into Fortran only a subsetof the C++ features can be mapped. Therefore only a restricted set of CI’s can be usedor implemented by Fortran. The restrictions are

33

• only CI classes, no CI libraries,

• no constructors,

• no operator nor method overloading,

• only methods returning void and accepting argument types listed in the followingsection.

9.1.1 Parameter Conversion

In the standard Fortran programing language no structured types like string or array (=vector) of a type are expressible.

On the other hand such structures are needed to implement a type safe messagepassing.

Therefore the interface is defined in such structures like an array which aggregatesthe information about number, type of data and the data itself to be transmitted betweendifferent processes. Hence, a translation of these structures to fundamental Fortran datatypes is needed.

Translation to Fortran Types:interface type =⇒ fortran representation

fundamentalschar =⇒ characterint2 =⇒ integer*2int4 =⇒ integer*4int8 =⇒ integer*8real4 =⇒ real*4real8 =⇒ real*8

structuresstring =⇒ integer*8, character

array<interface fund.> =⇒ integer*8, fortran fund.For example the interface signaturevoid firstClass::f (const real8, array<real8> &)has to be implemented bysubroutine firstClass_f_impl(accuracy, sx,x)real*8 accuracyinteger*8 sxreal*8 x(sx)

9.1.2 Functions for construction, destruction and result handling.

create a new CI object C: void new_CI(char *rlib, char *path, char *host, int *simu_handle)Fortran: subroutine new_simu(rlib,path,host,simu_handle)character* rlibcharacter* pathcharacter* hostinteger*8 simu_handle

34

if the zero terminated strings rlib, path and host describe a valid name and locationof a simulation service, new_simu will start the simulation path/rlib on the machinehost and simu_handle becomes a positive handle for this simulation process.

On failure simu_handle is set to 0.If host is the empty string ’\0’, the localhost is chosen.If rlib is the empty string a local simulation object is created in the current process.

In this case the corresponding service object must be linked to the current executable.

release a simulation object C: void rel_CI(int *ciname_handle)Fortran: subroutine rel_ciname(ciname_handle)integer*8 ciname_handleIf ciname_handle is a valid handle (obtained by a call to new_ciname) the dedicated

ciname-process will terminate.Further calls of ciname_<method>(ciname_handle, <param>, res_handle) – see be-

low – will have no effect apart from that ciname_handle and res_handle will be set to0.

All result handles obtained via ciname_handle become invalid.

receive the result(s) of a former cinamelation call C: void recv_ciname(int *res_handle)Fortran: subroutine recv_ciname(res_handle)integer*8 res_handleIf neither res_handle nor -res_handle is a valid handle obtained by a call of the kind

ciname_<method>(ciname_handle, <param>, res_handle), res_handle is set to -2.If res_handle was given as a negative value of a valid handle, recv_ciname waits for

the result answer, then sets res_handle to -1 and finally writes the result values into thevariable(s) given before (via <param>) to the corresponding call of ciname_<method>(ciname_handle,<param>, res_handle).

If res_handle is positive (and a valid result handle) recv_ciname tries to receivethe result answer. If this is already available the result is written into the variable(s)as above and sets res_handle to -1. If the result is not yet available res_handle isunchanged.

IMPORTANT:Please ensure that at the time recv_ciname is called, the variables in <param> are

still in scope.Otherwise your stack will be corrupted!!

call a ciname method C: void ciname_<method>(int *ciname_handle, <param>, int*res_handle)

Fortran: subroutine ciname_<method>(ciname_handle, <param>, res_handle)integer*8 ciname_handle<param> Fortran parameter of <method>integer*8 res_handleIf ciname_handle is not a valid handle obtained by a call to new_ciname or if the

ciname-process died in the mean time, ciname_handle will be set to 0 and the call hasno further effect.

35

Otherwise the method <method> of the cinamelation dedicated by ciname_handleis called with the parameter <param> and ciname_handle is unchanged.

If either the result is already available (due to a local cinamelation object, see undernew_ciname) or no result is expected (all parameter in <param> are const) res_handlewill be set to 0.

If res_handle was given as a negative number, this call waits for the result answerand sets res_handle to -1.

In all other cases res_handle is set to a positive number which can be used to receivethe result later on using recv_ciname.

9.2 JavaThere is already a prototyp of a Java environment using ??? which embedding Javaclasses into the CTL framework via tcp/ip.

10 Security

10.1 authentification

10.2 pipes: filtering of stdout

11 Architectural OverviewFigure \ref{fig::ctl_arch} shows an abstract view of CTL’s layered architecture. Thebottom layer shows the available communication channels. It is possible to add newchannels, e.g. new protocols. The second layer also called middleware provides acommon interface to different communication channels. Here the basic programmingmodels are located. Similar to MPI or PVM the CTL offers a message passing inter-face. On top of the message passing interface a remote message invocation mechanismsimilar to CORBRA or JAVA-RMI is implemented. The application area consists ofadditional CTL service components and user code.

filename /ul/platon/rainer/ctlDoc/ctl_usermanual/figures/ctl_arch.pdf

11.1 preprocessorIn the current CTL implementation the C-preprocessor is used to generate from the CIdefinition the functions needed to perform the remote invocations. This has the advan-tage that no other tool than the C++ -Compiler is needed to generate CTL components.Obvious disadvantages are the limitations of the preprocessor and the strange compilermessages if inside a macro expansion a compile time error occurs.

A consequence of the first point is the CI syntax the number of arguments in a listmust be explicitly given and that a type specifier may not contain a comma, see the<CI-grammatic>. A seperate CI syntax checker circumvents the second point.

36

12 RequirementsThe CTL is a C++ template library and has therefore some requirements to the under-lying compiler technology. In its simplest configuration the CTL just depends on thecompiler and the availability of a Unix TCP-IP sockets implementation. In the next twosections the compiler and third-party library dependencies of the CTL are descibed indetail.

12.1 Compiler RequirementsThe compiler has to support partial template specialisation. The CTL is intensily testedwith the gcc compiler suite under Linux. The CTL works with gcc release versions 2.95and above.

12.2 Communication Channel DependenciesThe CTL can use different communication channels. The availability of the protocol ona plattform decides whether a channel can be used or not. The minimum requirementis that there is a TCP-IP socket implementation.

37

13 Grammatic of the Component InterfaceThe CTL interface description is defined in terms of C-macro definitions which areexpanded to the functions which perform the data serialisation and transport. Due tothe fact, that the C-preprocessor can not count lists, at end of each declaration thenumber of arguments must be given. The following grammatic valid CI’s.

38

ident → valid C identifiernumargs → integer in {0, ..., maximal Args}counting the entries in a listid → integer in {1, ..., maximal ID }representing a function IDop → overloadable C operatorfuncname → ident | operator optype → [const] ident | [const] ident<type> | ([const] ident,(type [,type] ), numargs) | type*typelist → () [const], 0 | ( type [,type] ) [const], numargsfuncsign → type , funcname , typelistconstructor → #define CTL_Constructorid typelist

[#define CTL_ConstructoridThrows typelist]method → #define CTL_Methodid funcsign

[#define CTL_MethodidThrows typelist]staticmethod → #define CTL_StaticMethodid funcsign

[#define CTL_StaticMethodidThrows typelist]function → #define CTL_Functionid funcsign

[#define CTL_FunctionidThrows typelist]functiontmpl → #define CTL_FunctionTmplid funcsign , typelist

[#define CTL_FunctionTmplidThrows typelist]classentry → method | staticmethod | constructorclassbody → #include CTL_ClassBegin

classentry [ classentry ]#include CTL_ClassEnd

class → #define CTL_Class ident[#define CTL_Extends typelist ]classbody

classtmpl → #define CTL_ClassTmpl ident , typelist[#define CTL_Extends typelist ]classbody

libentry → class | classtmpl | function | functiontmpl | subliblibbody → #include CTL_LibBegin

libentry [ libentry ]#include CTL_LibEnd

library → #define CTL_Library identifierlibbody

sublibentry → class | classtmpl | function | functiontmpl | subsublibsublibbody → #include CTL_LibBegin

sublibentry [ sublibentry ]#include CTL_LibEnd

sublib → #define CTL_SubLibrary identifiersublibbody

subsublibentry → class | classtmpl | function | functiontmpl | subsubsublibsubsublibbody → #include CTL_LibBegin

subsublibentry [ subsublibentry ]#include CTL_LibEnd

subsublib → #define CTL_SubSubLibrary identifiersubsublibbody

subsubsublibentry → class | classtmpl | function | functiontmplsubsubsublibbody → #include CTL_LibBegin

subsubsublibentry [ subsubsublibentry ]#include CTL_LibEnd

subsubsublib #define CTL_SubSubSubLibrary identifiersubsubsublibbody

fwddclr → CTL_ClassFwd(identifier)interface → library | class | classtmpl | fwddclr

39