home *** CD-ROM | disk | FTP | other *** search
- Xref: sparky comp.lang.c++:20106 comp.std.c++:2149
- Path: sparky!uunet!spool.mu.edu!howland.reston.ans.net!paladin.american.edu!darwin.sura.net!mlb.semi.harris.com!travis.csd.harris.com!amber!bill
- From: bill@amber.csd.harris.com (Bill Leonard)
- Newsgroups: comp.lang.c++,comp.std.c++
- Subject: Re: Callbacks -- suggested approaches??
- Date: 28 Jan 1993 22:41:49 GMT
- Organization: Harris CSD, Ft. Lauderdale, FL
- Lines: 108
- Distribution: ssd
- Message-ID: <1k9nfdINN56n@travis.csd.harris.com>
- References: <DAVIDM.93Jan25171343@consilium.com> <rmartin.728090477@stripe>
- NNTP-Posting-Host: amber.ssd.csd.harris.com
-
- In article <rmartin.728090477@stripe>, rmartin@stripe.Rational.COM (Bob Martin) writes:
- > Passing messages between processes is always a challenge, especially
- > when what you really want to do is pass messages between two objects
- > which happen to live in different processes. It would be very nice if
- > the sending and receiving objects did not know that the message was
- > crossing a process boundary. Below is described a technique for
- > achieving this.
- >
- > Unfortunately, theB lives in another process. No problem. Create an
- > abstract class called AbstractB. It contains a set of pure virtual
- > functions defining all the messages that B can receive. B will
- > inherit from AbstractB. So will another class called BSurrogate.
- > BSurrogate knows which process the real B object lives in and knows
- > how to convert the message into a packet and ship it to that process.
- > The packet will contain all the arguments to X, an identifier denoting
- > that it represents an X message and the identifier of the B object to
- > which the message should be sent.
- >
- > When the process receives the it looks up the name of the object in a
- > dictionary. The dictionary associates the name with a derivative of
- > the class Reciever. BReceiver is derived from Receiver, and knows how
- > to unpack the X packet. It also knows where the B object is (Probably
- > it contains a pointer to it), so it unpacks all the arguments and then
- > sends the message to its B object.
-
- We have implemented a scheme very much like this in a project here, with
- some minor differences. In so doing we have learned some lessons that
- I will pass on for what they're worth. First, a brief description of
- our scheme:
-
- For each class of object that needs to implement inter-process
- communication, we define 3 classes: There's the AbstractB as Bob says
- above, there's the BSurrogate derived from AbstractB, and there's also the
- BReal derived from AbstractB. AbstractB just defines the interface to the
- B class of objects. BSurrogate implements the interface by passing
- messages to another process. BReal is the actual implementation of the
- functionality of B.
-
- We also define a class called Router (similar to Bob's Receiver class).
- For each class B, there is a BRouter class, derived from Router, that
- receives the messages that BSurrogate sent and calls the appropriate
- function using a pointer to a BReal object.
-
- By the way, we don't "look up the object in a dictionary". We just pass
- the address of the BRouter object as part of the message; the generic
- message handler casts that value to a Router * and calls a virtual function
- using the resulting pointer. (More on this below...)
-
- Now, the lessons learned:
-
- 1. Adding a function to the interface to B is a real pain! You must add
- the function signature in 3 places: AbstractB, BSurrogate, and BReal.
- You generally also have to invent a new type of message, which entails
- adding code to BRouter to know how to interpret that new message.
-
- 2. Getting these objects created is often non-trivial. Someone has to
- create the BReal object in the process where he is to reside. That
- someone must typically also create the BRouter object, who needs to
- keep a pointer to the BReal object around so he can call member
- functions of it. Then the BSurrogate object must be created in the
- other process, and he needs to know some ID for the BRouter object so
- that messages he sends get to the right place.
-
- We've had a few cases where the BSurrogate and BReal objects each
- needed to talk to the other. That further complicates the creation,
- usually entailing having one of the objects send a message to the
- other one telling him the address he should use if he wants to
- initiate messages in the other direction.
-
- 3. Destroying these objects is likewise tricky.
-
- 4. If, for some reason, you need to make copies of a B object, then that
- entails having BSurrogate implement a copy constructor that can send a
- message over to BReal telling him to make a copy of himself and his
- BRouter.
-
- 5. If I had to do this over, I would make the BReal object use multiple
- inheritance, deriving it from both the AbstractB class and the Router
- class. That way, the BReal object can be its *own* Router, thus
- eliminating the need to create an extra object and coordinating its
- creation and destruction.
-
- 6. If you ever screw up a message and pass the wrong Router pointer, you
- will get very bizarre and hard-to-track-down bugs. This method has
- the advantage of being fast, but we still talk about adding some kind
- of dictionary so that we can at least verify that the Router pointer
- we have is valid.
-
- We made a small attempt at automating the creation of the BSurrogate and
- BRouter classes, with no success, but that doesn't mean it couldn't be
- done. If I had to do this for a very large number of classes and
- functions, I'd probably develop a very-high-level language of some kind to
- describe the interface, so that I could automate at least parts of this.
-
- Well, hope this helps somebody...
-
- --
- Bill Leonard
- Harris Computer Systems Division
- 2101 W. Cypress Creek Road
- Fort Lauderdale, FL 33309
- bill@ssd.csd.harris.com
-
- These opinions and statements are my own and do not reflect the opinions or
- positions of Harris Corporation.
- ---------------------------------------------------------------------------
- Prism: A place for light waves that commit minor refractions.
- ---------------------------------------------------------------------------
-