moss-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Moss-devel] CVS: moss/rmc/doc README,NONE,1.1 README.developer,NONE,1.1


From: Alexander Feder <address@hidden>
Subject: [Moss-devel] CVS: moss/rmc/doc README,NONE,1.1 README.developer,NONE,1.1 index.html,NONE,1.1 rmc.2.lyx,NONE,1.1
Date: Sun, 23 Jun 2002 09:27:50 -0400

Update of /cvsroot/moss/moss/rmc/doc
In directory subversions:/tmp/cvs-serv2212/doc

Added Files:
        README README.developer index.html rmc.2.lyx 
Log Message:
added rmc


--- NEW FILE ---
2001-12-08 Manfred Morgner

RMC "remote methode call" is a library for C++ classes to provide
call to remote C++ classes. The simple principe is, that a local
C++ class is able to let a server instanciate a compatible class
remotely and use it there.

The difference to CORBA, SOAP, RPC and familiar libraries is,
that RMC does not need a special interface script (as IDL) and
no additional external libraries and translators. RMC is a
very compact library without expensive network- and interface-
coding for the programmer who uses it.

RMC is not completely endian save. but this will follow.
Currently it is tested on and between Linux and WinNT4. It should
run on other U**x derivates than Linux and also other Win32
derivates than WinNT4.

To create the network connect code, RMC uses an code generator.
This code generator is currently out of date.

--- NEW FILE ---
To build RMC.2 you will need:

(Minimal version numbers-->)
automake version 1.5
autoconf version 2.5x
libtool version 1.3.x
perl v5.005 

(and your normal c/c++ compiler suite)

RMC.2 is platform independant, but we are working on a nice way
for windows easy build support (it does build)

RMC.2 is tested (and works :-)  on debian woody

--- NEW FILE ---
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
           "http://www.w3.org/TR/REC-html40/loose.dtd";>
<html>
<meta name="GENERATOR" content="TtH 2.92">
 
 
   
   
<title> RMC.2</title>
 
<h1 align="center">RMC.2 </h1>

<p>

<h3 align="center">(c) 2001 Manfred Morgner </h3>

<p>
 <h1><a name="tth_chAp1">
Chapter 1 </a><br />Basics</h1>

<p>
 <h2><a name="tth_sEc1.1">
1.1</a>&nbsp;&nbsp;What is RMC.2?</h2>

<p>
     <h3><a name="tth_sEc1.1.1">
1.1.1</a>&nbsp;&nbsp;RMC in general</h3>

<p>
RMC stands for ``Remote Methode Call''. The first release was designed
to enable calling remote methods of C++ objects. Further, the first version
was designed to use DCE-RPC, because it was intended to support lots of 
platforms
and provide amazing features like

<p>

<ul><p>
<li> Endianess</li>
<p>
<li> Security</li>
<p>
<li> Routability</li>
<p>
<li> Multiple protocols</li>
</ul>
Unfortunately, there was a single problem within DCE-RPC. The DCE-Goup provides
DCE-RPC for free only if used for academic or private purposes. Otherwise, the
user (in this case we) had to pay 500.000,- USD.

<p>
Now, as we are a free project, we are neither willing nor able to pay such an
amount of money. Thus we tried to make use of FreeDCE. FreeDCE is a project
hosted on SourceForge (http://sourceforge.net/projects/freedce), that tries
to provide Microsoft-OLE to Linux and familiar platforms. One part of this 
project
is a free implementation of DCE-RPC.

<p>
Wow, that sounds good, and after some porting, the Win32-RMC-Code was running
on Linux-i86 well  <font size="-2">AND</font> is able to communicate between 
Win32 and Linux-i86.
Great! But later, a problem was found, that I was unable to solve. Now the 
problem
with DCE-RPC was technical. The FreeDCE implementation is unable to remotely
allocate memory. Remote memory allocation is a ``must have'' for RMC to
work. Thus, FreeDCE was unable to serve our project. This is very sad, as 
DCE-RPC
would really be great if it would work in the way we need it. It is stable and
fast and .... ok, forget it, we can't use it.

<p>
     <h3><a name="tth_sEc1.1.2">
1.1.2</a>&nbsp;&nbsp;RMC.2</h3>

<p>
RMC.2 is the successor of RMC. It is also called ``RMC for <i>any</i> 
transport''.
This means, the RMC system is recoded to simply support any transport through
dynamically loadable libraries. The RMC transport library API is once defined
and gives anyone the possibility, to implement his own transport.

<p>
For the first time, RMC.2 may not support different endianess and different
sizes of base types (like 16, 32 and 64 bit systems) as DCE-RPC does. This 
support
will go into the primary function, not into the transport. So, if anyone creates
a transport library, this library is endian independend in each case. Means,
the transport is only a transparent.

<p>
Since RMC (as RMC.2) uses authorization, it is a good idea, to encrypt the data
before the transport. But no one directs you to do so. 

<p>
 <h2><a name="tth_sEc1.2">
1.2</a>&nbsp;&nbsp;Technicals</h2>

<p>
     <h3><a name="tth_sEc1.2.1">
1.2.1</a>&nbsp;&nbsp;Function calls in C</h3>

<p>
C enables you to call functions by function pointers easily. The syntax to 
define
a function pointer is a little bit unusual, but calling functions behind such
pointers is really easy.

<p>

<dl compact="compact"><dt><b></b></dt>
        <dd>
int&nbsp;(*fnFoo)(char);
</dl>
Declares a variable ``fnFoo'' that can hold a function pointer to a function
getting a single ``char'' variable and returning an ``int'' value.
There are two possible assignments:

<p>

<dl compact="compact"><dt><b></b></dt>
        <dd>
1)&nbsp;fnFoo&nbsp;=&nbsp;0;&nbsp;//&nbsp;old:&nbsp;..&nbsp;=&nbsp;NULL

<p>
2)&nbsp;fnFoo&nbsp;=&nbsp;Foo;&nbsp;//&nbsp;where&nbsp;Foo&nbsp;may&nbsp;be&nbsp;defined&nbsp;as&nbsp;'int&nbsp;Foo(char&nbsp;c)'
</dl>
The first form is possible because any pointer variable accepts a ``0'',
the second one is the real assignment. If we wish to call a function behind
the variable, we can use the pointer, as if it were defined as a function:

<p>

<dl compact="compact"><dt><b></b></dt>
        <dd>
fnFoo('g');
</dl>
That's mainly all for the C syntax.

<p>
     <h3><a name="tth_sEc1.2.2">
1.2.2</a>&nbsp;&nbsp;Methode calls in C++</h3>

<p>
C++ uses the same rules for calling functions as C does. But the difference
is the use of method pointers. (Better known as the implicit argument.) At 
least,
we have to find out, that methods are different from simple functions. This
is, because ``methods'' (functions inside a class) are associated to their
class.

<p>
This association results in a more cryptic syntax and also in a more complex
calling construct:

<p>

<dl compact="compact"><dt><b></b></dt>
        <dd>
class&nbsp;CGuu

<p>
&nbsp;&nbsp;{

<p>
&nbsp;&nbsp;public:&nbsp;int&nbsp;Foo(char&nbsp;c);

<p>
&nbsp;&nbsp;};&nbsp;//&nbsp;class&nbsp;CGuu

<p>
int&nbsp;(CGuu::*fnFoo)(char);
</dl>
As seen in the declaration, the class association of a method can't be splitted
from the class itself. C++ uses this syntax to hide the truth. To let the 
runtime
system know, from what class the method is, method calls are enhanced internally
during the compile-process. The real call for the Method ``Foo'' is:

<p>

<dl compact="compact"><dt><b></b></dt>
        <dd>
int&nbsp;Foo(this,&nbsp;char);
</dl>
where ``this'' is the pointer to the used object instance.

<p>
Unfortunately, the usual C++ compilers reject this syntax explicitely if we
try to call a method by a pointer. Thats why we have to use the following 
construct:

<p>

<dl compact="compact"><dt><b></b></dt>
        <dd>
CGuu&nbsp;o;

<p>
o::meFoo('g');
</dl>
Ok, this calling convention does not contain more information than the fist
one, but it is a really headbanging syntax. But why? The reason is simple, but
it is hard to explain.

<p>
Imagine that you have a class with a member variable in it:

<p>

<dl compact="compact"><dt><b></b></dt>
        <dd>
class&nbsp;CGuu

<p>
&nbsp;&nbsp;{

<p>
&nbsp;&nbsp;int&nbsp;m_nNum;

<p>
&nbsp;&nbsp;public:&nbsp;int&nbsp;Foo(char&nbsp;c);

<p>
&nbsp;&nbsp;};&nbsp;//&nbsp;class&nbsp;CGuu
</dl>
and you instanciate more than one Class:

<p>

<dl compact="compact"><dt><b></b></dt>
        <dd>
CGuu&nbsp;o1,&nbsp;o2;
</dl>
In this case, you get (inside the classes):

<p>

<b>2 variables:&nbsp;&nbsp;</b>

<p>

<dl compact="compact"><dt><b></b></dt>
        <dd>
o1.m_nNum;

<p>
o2.m_nNum;
</dl>

<p>

<b>1 methode:&nbsp;&nbsp;</b>

<p>

<dl compact="compact"><dt><b></b></dt>
        <dd>
int&nbsp;CGuu::Foo(char&nbsp;c);
</dl>
No one wants it and it is not possible to duplicate the binary code for a second
class instance, and this is the problem. Our Foo methode should be defined as:

<p>

<dl compact="compact"><dt><b></b></dt>
        <dd>
int&nbsp;CGuu::Foo(char&nbsp;c)

<p>
&nbsp;&nbsp;{

<p>
&nbsp;&nbsp;return&nbsp;m_nNum&nbsp;+=&nbsp;(int)&nbsp;c;&nbsp;//&nbsp;sorry

<p>
&nbsp;&nbsp;}
</dl>
What, if we have two objects, and try to write to ``m_nNum''? We need
to know, what object is meant. That's why, in physical point of view, the call
is enhanced:

<p>

<dl compact="compact"><dt><b></b></dt>
        <dd>
o1.Foo('g');&nbsp;<b><i>to</i></b>&nbsp;CGuu::Foo(&amp;o1,&nbsp;'g');
</dl>
Also the execution has to be changed internally:

<p>

<dl compact="compact"><dt><b></b></dt>
        <dd>
int&nbsp;CGuu::Foo(char&nbsp;c)&nbsp;<b><i>to</i></b>&nbsp;CGuu::Foo(CGuu*&nbsp;this,&nbsp;char&nbsp;c)

<p>
&nbsp;&nbsp;{

<p>
&nbsp;&nbsp;return&nbsp;m_nNum&nbsp;+=&nbsp;(int&nbsp;c);&nbsp;<b><i>to</i></b>&nbsp;this-&#62;m_nNum&nbsp;+=&nbsp;c;

<p>
&nbsp;&nbsp;}
</dl>
Now it is defined which member of which object will be changed. So you may guess
that we are able to store a method pointer to'' int CGuu::Foo(char)''
like this:

<p>

<dl compact="compact"><dt><b></b></dt>
        <dd>
int&nbsp;(*meFoo)(CGuu*,&nbsp;char);
</dl>
and assign the real address like this:

<p>

<dl compact="compact"><dt><b></b></dt>
        <dd>
meFoo&nbsp;=&nbsp;o1.Foo;
</dl>
But this will not work. This is not a technical reason, but a question of the
language definition. Our keyword here is: <i>type savety</i>. If we were able
to call a method like above, the compiled had no chance to protect us from 
mistakes.
The working and typesafe syntax for a pointer to the methode Foo in the class
CGuu is:

<p>

<dl compact="compact"><dt><b></b></dt>
        <dd>
<b>int&nbsp;(CGuu::*meFoo)(char);</b>
</dl>
Here we can see how the class is associated to the methode pointer. Unusual,
but it works, and this is the way we need to go if we wish to build a ``remote
method table''. Finally the call convention for using the object ``o1''
from the example above is:

<p>

<dl compact="compact"><dt><b></b></dt>
        <dd>
<b>meFoo&nbsp;=&nbsp;&amp;CGuu::Foo;</b>&nbsp;//&nbsp;associates&nbsp;the&nbsp;pointer&nbsp;to&nbsp;the&nbsp;methode

<p>
<b>(o1.*meFoo)('C');</b>&nbsp;//&nbsp;calls&nbsp;the&nbsp;methode
</dl>
If you look at this construct, you might face the problem that the pointer 
assignment
seems unable to handle method overloading. But this is not the case. If you
can't believe, try it for yourself. But as you may see, the method pointer 
definition
contains the complete calling conventions, and so also the exact methode 
assignment.

<p>
 <h2><a name="tth_sEc1.3">
1.3</a>&nbsp;&nbsp;Calling remote methods</h2>

<p>
     <h3><a name="tth_sEc1.3.1">
1.3.1</a>&nbsp;&nbsp;Some premission</h3>

<p>
When we want to call a remote method, we need a remote object. Each object on
the client side must have an associated object on the server side. This means
that each object on our (client-) side is in control of its very own 
representation
on the server side.

<p>
>From the point of view of the physical transport, the client side is called
``proxy'' and the server side is called ``stub''. A ``proxy''
is the representative of the server on the client side, while the ``stub''
is representing the client on the server side.

<p>
RMC is an open source project. This means that the client is free to use and
modify for each user, while the server is free for each ``service provider''.
To protect the system against brain damaged ``users'', who are trying
to break RMI servers, we only have to concentrate on the server. Each user is
free to manipulate his client software and there is no way to ensure the 
behavior
of the client. We can see this as a problem, but it is also a plus. Double sided
security is hard to manage and includes higher risk of mistakes when two groups
of developers believe that the other will take care of a certain problem.

<p>
     <h3><a name="tth_sEc1.3.2">
1.3.2</a>&nbsp;&nbsp;A little problem</h3>

<p>
There is a little problem(?) using RMC as shown below. This problem is typical
for remote object access, so I will describe it and give the solution.

<p>
The server has to know the classes we wish to use from the client side. This
does not mean it needs the code or that it has to know for what purpose the
classes are implemented. But it has to know the declaration of the ``remote
enabled methods''. That's why we need a way of synchronisation. There are
typical two ways for doing so.

<p>

<h4>OLÈ</h4>

<p>
This first way is what Microsoft uses known as the OLE (Object Linking and 
Embedding)
mechanism, sometimes called ``ActiveX''. OLE is a high sofisticated scheme
for IPC (interprocess communication). It uses ``Method descriptions''.
You are able to remotely instanciate ``anything like an object'' for your
purspose. You are not in control what it is, but it is somethings that pretends
to support your wishes. After instanciation of that thing, OLE is able to look
what methode the ``thing'' will support. The methods are characterized
by names, calling argument descriptions and GUID's (global unique identifiers).

<p>
I don't wish to explain OLE here, because we won't use it in RMI. If you're
interested, there is lots of documentation out there. Some documentation is
partially correct.

<p>

<h4>ROC</h4>

<p>
Sorry, this is a synthetic name, because I don't know any official one. ROC
means ``remote object call'' and will describe a different mechanism than
OLE. Using ROC we have lot of disadvantages compared to OLE, but the advantages
are more valuable. ROC is (do I need to write this) the mechanic for calling
remote methods used in RMI.

<p>
A ROC application needs to know what's up in both sides of the system. Not 
everything,
but from the technical point of view. When a client requests an object, the
server has to instanciate it or not (when it's unknow). There is no legal way
to construct a nonmatching object on the server side. RMI enabled objects are
enhanced with some features, one of them is the ``remote method table''
(RMT). Like the VMT (virtual method table) a RMT contains links to methods.
Only objects containing the same RMT's are compatible. RMT's can be inherited.
This means that any class, derived from a server side RMI class, is compatible
to the same client side base class. This means also that ``client side 
inheritance''
is at least problematic. Currently we don't support this by the RMI framework,
but this does not mean that you are unable to use it. We will take a deeper
look to this some later.

<p>
To ensure, that clients and their servers are able to understand each other,
we use some helpers. Instead of implementing remote objects by ourself, we use
a code generator. The code generator frees us from knowing RMI in detail and
ensures matching classes on both sides of the system. The starting point for
the code generator is a single (simple) header file which declares your object.
For example:

<p>

<dl compact="compact"><dt><b></b></dt>
        <dd>
class&nbsp;CThing

<p>
&nbsp;&nbsp;{

<p>
&nbsp;&nbsp;public:

<p>
&nbsp;&nbsp;RMC&nbsp;int&nbsp;Access(char&nbsp;cSign);

<p>
&nbsp;&nbsp;};&nbsp;//&nbsp;class&nbsp;CThing
</dl>
As you can see, the only difference between a normal and a RMC enabled class
is the sign ``RMC'' before the methode declaration. The code generator
implements the RMC methods in the header files. This means, the cxx-files do
not contain RMC method implementations.

<p>
 <h1><a name="tth_chAp2">
Chapter 2 </a><br />How it works</h1>

<p>
 <h2><a name="tth_sEc2.1">
2.1</a>&nbsp;&nbsp;The main components</h2>

<p>
For calling remote methods, we need a special environment and some 
preconditions.
We need at least:

<p>

<ul><p>
<li> a server</li>
<p>
<li> a client</li>
<p>
<li> a transport</li>
</ul>

<p>
     <h3><a name="tth_sEc2.1.1">
2.1.1</a>&nbsp;&nbsp;The Server</h3>

<p>
Typicaly a remote method call needs a dedicated object for each client object
on the remote site. Each server object deals with one client object.

<p>
The server needs a class factory to construct these objects. Further, it needs
to keep track of the client requests and the addressed server objects.

<p>
Further the server needs a ``call manager'' to associate the incoming
method call with the appropriate object instance. This is neccessary, because
the server object life time is (in the normal case) identical to the client
side object life time. 

<p>
Because servers on the internet are subject of attacks, the server needs some
authentication algorithm.

<p>

<h4>The Object Factory</h4>

<p>
The server has to know what it has to instanciate when an object request comes
in. This means that the server code should contain any class definition and
implementation it is supposed to provide. This comes down to the implementation
of a class factory.

<p>
For example: If a client wants access to a device using RMC, the server has
to know the which class the client wants to use. The server side implementation
is specific for the device, while the client side implementation is more or
less abstract.

<p>
Imagine that you have a remote weather station and wish to request the 
temperature.
In this case, the client only needs to know it can call ``GetTemperature(..)'',
but the server has to support the hardware by using drivers or libraries. So
if the client requests a thermometer object on the server side, the server has
to instanciate a class, that is compatible with the client side class, but (in
difference to the client class) knows how to handle the thermometer.

<p>

<h4>The Call Manager</h4>

<p>
After the client opened a session on the server, the server handles the incoming
calls. Application servers have to handle multiple (many) clients with multiple
objects per client. Making a difference between objects from the same client
and objects from a different client does not make any sense, so we are in the
happy situation, that we only have to develop a mechanism to associate client
objects to there server representations. 

<p>
     <h3><a name="tth_sEc2.1.2">
2.1.2</a>&nbsp;&nbsp;The Client</h3>

<p>
On the client side, we need a mechanism to handle remote calling. Its main 
purpose
is to handle these operations as transparent as possible. Further the client
needs a remote calling mechanism, that has to be ... yes ... as transparent
as possible.

<p>
Using a black box concept appears the best way. The only precondition to use
it is that the developer, who uses the RMC framework, trusts the mechanism.
But ``trusting black boxes" is a typical design paradigm in object
oriented programming. RMC.2 uses a simple model, that should be easy to 
understand.

<p>

<blockquote>``Remote methods are executed remotely''
</blockquote>
In consequence of this paradigm, RMC.2 requests, that RMC specific methods are
kept unchanged on the client side. The code generator generates the remote 
calling
code and this code is ``untouchable''.

<p>

<h4>The Remote Object Connector</h4>

<p>
(ROC again ;-). Any programmer understands that a client/server application
has - in any way - to deal with ``connecting the client to the remote side''.
And this is point, where RMC hooks in. If a client object is called to connect
to the server, RMC instanciates his counterpart on this server. RMC does not
need any other call to activate anything on the server. If the ``Connect(..)''
call ist successfull, the client object is ready to call his representitive
on the server side. Going this way:

<p>

<dl compact="compact"><dt><b></b></dt>
        <dd>
CWeatherMonitor&nbsp;oWM(``the_server_address'');

<p>
double&nbsp;dTemperature&nbsp;=&nbsp;oWM.GetTemerature();
</dl>
That's all for the first call. The generated call takes care about any RMC 
specific
problems.

<p>
 <h1><a name="tth_chAp3">
Chapter 3 </a><br />In the deep</h1>

<p>
 <h2><a name="tth_sEc3.1">
3.1</a>&nbsp;&nbsp;The Server</h2>

<p>
     <h3><a name="tth_sEc3.1.1">
3.1.1</a>&nbsp;&nbsp;Components</h3>

<p>
A RMC server application consists of the following basic parts:

<p>

<ul><p>
<li> Server specific Client code (stub)</li>
<p>
<li> A single Class Factory, capable to generate client stub of all application 
imanent
classes</li>
<p>
<li> Some transport libraries</li>
<p>
<li> A single runtime frame, holding the parts together.</li>
</ul>

<p>

<h4>Stub classes and the Class Factory</h4>

<p>
..are client representations on the server side. Typically, stubs are a part
of the server code. This means, stubs are <i>trusted code</i>. In a simple
case, rmcgen creates an empty stub for the programmwer, where the programm 
inserts
his code in. Doing so is the easies way to implement a stub class for any client
application. the class factory instanciates only the requested class and handles
them for the client. Rmcgen generates the files:

<p>

<ul><p>
<li> &lt;name&#62;_c.h</li>
<p>
<li> &lt;name&#62;_c.cxx</li>
</ul>
and generates/modifies:

<p>

<ul><p>
<li> RmcClassFactory.cxx</li>
</ul>
In normal case, this is all you need to make a RMC server stub working. You
may imlpement some functions for the remote methods, to do anything usefull.

<p>
A more suffisticated, and much more usefull way for this is, to derive one or
more class(es) from the stub class. In this case, the class factory has to 
decide,
wich class is to instanciate for the client. In the first case (a single class
derived from the stub class) it is easy to decide, because we assume, that only
the derived class is to instanciate. So, if the client (e.g.) requests the class
with the RTTI ``0x00beef00'', the class factory instanciates not this
class but the derived class.

<p>
A simple example is a thermometer in a weather station. If each weather station
contains a thermometer of a specific type, a single station contains only one
thermometer of exactly one type. Thats why the server contains only a driver
for this thermometer. To keep the client free from the specific properties of
different weather stations == different thermometers, we implement a abstract
class ``CThermometer'' for RMC. On the server side, we may derive a concrete
thermometer class, that supports the device specifics and is amble to return
the temerature, independend how the driver has to query the device.

<p>
More than one derived classes on the server side are possible, in this case
the application developer has to decide, on wich way the server choose the right
class. Currently we will not support this version with our source code 
generator.
You may do it by hand - if neccessary.

<p>

<h4>Transport Libraries</h4>

<p>
..are used to make the remote call. RMC.2 is strong modular and provides a 
transport
library API. A single server is able to use all given transport libraries the
same time. He simply loads the libraries of his interest with his transport
library loader, that's all. Each transport library is given a backward callback
to the server by the server. For further details, please look into the socket
transport library in the source tree.

<p>

<h4>The runtime frame</h4>

<p>
..is a standard application frame, used to spawn the neccessary threads, load
the configuration and the transport libraries. Later in the development, we
will try to load modules for late bound RMC stubs, but as I said: later.

<p>
 <h2><a name="tth_sEc3.2">
3.2</a>&nbsp;&nbsp;The Client</h2>

<p>
A RMC client is much easier than a RMC server, because the client is simply
a specialized class. This means, a client application may contain not only an
unlimited amount of RMC classes (proxy classes), it is also able to hold classes
for different RMC servers. Rmcgen will generate the class implementation for
each RMC class consisting of two files:

<p>

<ul><p>
<li> &lt;name&#62;_c.h</li>
<p>
<li> &lt;name&#62;_c.cxx</li>
</ul>
where ``_c'' stand for Client.

<p>
Because RMC client classes are for remote acces, and mostly abstract for the
client, there is no reason to derive from them. But if you wish to do so, then
do so. But in this case you may accept some specials to keep the RMC automatic
alife.

<br /><br /><hr /><small>File translated from
T<sub><font size="-1">E</font></sub>X
by <a href="http://hutchinson.belmont.ma.us/tth/";>
T<sub><font size="-1">T</font></sub>H</a>,
version 2.92.<br />On  3 Sep 2001, 23:30.</small>
</html>

--- NEW FILE ---
#LyX 1.1 created this file. For more info see http://www.lyx.org/
\lyxformat 2.16
\textclass book
\language default
\inputencoding latin1
\fontscheme default
\graphics default
\paperfontsize default
\spacing single 
\papersize Default
\paperpackage a4
\use_geometry 0
\use_amsmath 0
\paperorientation portrait
\secnumdepth 2
\tocdepth 2
\paragraph_separation indent
\defskip medskip
\quotes_language english
[...1084 lines suppressed...]
long _RMC_size();
\layout Standard

Has to return the size of the binary data for the transport.
\layout Subsection

bool _RMC_put(TRmcData *&rpData, long nSize);
\layout Standard

Recieves a buffer for the data to send during the RMC transport.
 The size has to match with the result of the methode _RMC_size().
\layout Subsection

bool _RMC_get(TRmcData *pData, long nSize); 
\layout Standard

Recieves a buffer with data from the RMC transport to fill the object with
 life.
 Is for informational or for controlling purpose, dependend on the situation.
\the_end




reply via email to

[Prev in Thread] Current Thread [Next in Thread]