When you were using CORBA before, you will see that MCOP is much the same thing.
So the basic idea of CORBA remains: 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.
parameters are always incoming - the returncode 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.
MCOP doesn't have exceptions - use something else for error handling.
I don't know if that is a real weakness - something one would despereately need to survive.
Example: instead of
// CORBA idl struct Line { long x1,y1,x2,y2; }; typedef sequence<Line> LineSeq; interface Plotter { void draw(in LineSeq lines); };you write
// MCOP idl struct Line { long x1,y1,x2,y2; }; interface Plotter { void draw(sequence<Line> lines); };
Streams are declared similar to attributes, for instance:
// MCOP idl interface Synth_ADD : SynthModule { in audio stream signal1,signal2; out audio stream outvalue; };This does say that your object will accept two incoming synchronous audio streams, that are called signal1 and signal2.
By saying synchronous I mean: these are streams that deliver synchoneously 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 outvalue - that is what synchronous operation means.
This differs from CORBA mostly. However here it is:
are using 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.
are plain long's (expected to be 32 bit)
are using the C++ STL "vector" class.
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.
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 that
// 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 did 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 referencestring reference = server._toString(); printf("%s\n",reference.c_str());and go to the MCOP idle loopDispatcher::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");
back to index