MCOP for CORBA Users
Prev
Next

MCOP for CORBA Users

If you have used CORBA before, you will see that MCOP is much the same thing. In fact, aRts prior to version 0.4 used CORBA.

The basic idea of CORBA is the same: you implement objects (components). By using the MCOP features, your objects are not only available as normal classes from the same process (via standard C++ techniques) - they also are available to remote servers transparently. For this to work, the first thing you need to do is to specify the interface of your objects in an IDL file - just like CORBA IDL. There are only a few differences.

CORBA Features That Are Missing In MCOP

In MCOP there are no “in” and “out” parameters on method invocations. Parameters are always incoming, the return code is always outgoing, which means that the interface:

// CORBA idl
interface Account {
  void deposit( in long amount );
  void withdraw( in long amount );
  long balance();
};

is written as

// MCOP idl
interface Account {
  void deposit( long amount );
  void withdraw( long amount );
  long balance();
};

in MCOP.

There is no exception support. MCOP doesn't have exceptions - it uses something else for error handling.

There are no union types and no typedefs. I don't know if that is a real weakness, something one would desperately need to survive.

There is no support for passing interfaces or object references

CORBA Features That Are Different In MCOP

You declare sequences as “sequencetype” in MCOP. There is no need for a typedef. For example, instead of:

// CORBA idl
struct Line {
    long x1,y1,x2,y2;
};
typedef sequence<Line> LineSeq;
interface Plotter {
    void draw(in LineSeq lines);
};

you would write

// MCOP idl
struct Line {
    long x1,y1,x2,y2;
};
interface Plotter {
    void draw(sequence<Line> lines);
};

MCOP Features That Are Not In CORBA

You can declare streams, which will then be evaluated by the aRts framework. Streams are declared in a similar manner to attributes. For example:

// MCOP idl
interface Synth_ADD : SynthModule {
    in audio stream signal1,signal2;
    out audio stream outvalue;
};

This says that your object will accept two incoming synchronous audio streams called signal1 and signal2. Synchronous means that these are streams that deliver x samples per second (or other time), so that the scheduler will guarantee to always provide you a balanced amount of input data (e.g. 200 samples of signal1 are there and 200 samples signal2 are there). You guarantee that if your object is called with those 200 samples signal1 + signal2, it is able to produce exactly 200 samples to outvalue.

The MCOP C++ Language Binding

This differs from CORBA mostly:

  • Strings use the C++ STL string class. When stored in sequences, they are stored “plain”, that means they are considered to be a primitive type. Thus, they need copying.

  • longs are plain long's (expected to be 32 bit).

  • Sequences use the C++ STL vector class.

  • Structures are all derived from the MCOP class Type, and generated by the MCOP IDL compiler. When stored in sequences, they are not stored “plain” , but as pointers, as otherwise, too much copying would occur.

Implementing MCOP Objects

After having them passed through the IDL compiler, you need to derive from the _skel class. For instance, consider you have defined your interface like this:

// MCOP idl: hello.idl
interface Hello {
    void hello(string s);
    string concat(string s1, string s2);
    long sum2(long a, long b);
};

You pass that through the IDL compiler by calling mcopidl hello.idl, which will in turn generate hello.cc and hello.h. To implement it, you need to define a C++-class that inherits the skeleton:

// C++ header file - include hello.h somewhere
class Hello_impl : virtual public Hello_skel {
public:
    void hello(const string& s);
    string concat(const string& s1, const string& s2);
    long sum2(long a, long b);
};

Finally, you need to implement the methods as normal C++

// C++ implementation file

// as you see string's are passed as const string references
void Hello_impl::hello(const string& s)
{
    printf("Hello '%s'!\n",s.c_str());
}

// when they are a returncode they are passed as "normal" strings
string Hello_impl::concat(const string& s1, const string& s2)
{
    return s1+s2;
}

long Hello_impl::sum2(long a, long b)
{
    return a+b;
}

Once you do that, you have an object which can communicate using MCOP. Just create one (using the normal C++ facilities to create an object):

    Hello_impl server;

And as soon as you give somebody the reference

    string reference = server._toString();
    printf("%s\n",reference.c_str());

and go to the MCOP idle loop

Dispatcher::the()->run();

People can access the thing using

// this code can run anywhere - not necessarily in the same process
// (it may also run on a different computer/architecture)

    Hello *h = Hello::_fromString([the object reference printed above]);

and invoke methods:

    if(h)
        h->hello("test");
    else
        printf("Access failed?\n");
Prev
Next
Home


Would you like to make a comment or contribute an update to this page?
Send feedback to the KDE Docs Team