Changes

Jump to: navigation, search

IPDL/Five minute example

3,417 bytes added, 03:19, 18 July 2009
Implement your protocol's generated C++ interface
== Implement your protocol's generated C++ interface ==
 
Like Mozilla's IDL compiler, the IPDL compiler generates skeleton, concrete C++ implementations for the "abstract" classes it spits out. We'll add our "Hello, world!" printing code to those skeleton implementations in this step.
 
Open <code>$OBJDIR/ipc/ipdl/_ipdlheaders/mozilla/test/TestProtocolChild.h</code> and <code>$OBJDIR/ipc/ipdl/_ipdlheaders/mozilla/test/TestProtocolParent.h</code>. Look for the sections marked <code>// Skeleton implementation of abstract actor class</code>; you should see something like the following.
 
// ----- [in TestProtocolChild.h] -----
// Header file contents
class ActorImpl :
public TestProtocolChild
{
virtual nsresult RecvHello();
ActorImpl();
virtual ~ActorImpl();
};
// C++ file contents
nsresult ActorImpl::RecvHello()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
ActorImpl::ActorImpl()
{
}
ActorImpl::~ActorImpl()
{
}
 
// ----- [in TestProtocolParent.h] -----
// Header file contents
class ActorImpl :
public TestProtocolParent
{
virtual nsresult RecvWorld();
ActorImpl();
virtual ~ActorImpl();
};
// C++ file contents
nsresult ActorImpl::RecvWorld()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
ActorImpl::ActorImpl()
{
}
ActorImpl::~ActorImpl()
{
}
 
Looking past the odd fact that both skeletons are named "ActorImpl," note the substantial difference between the two skeletons: the ProtocolChild requires your C++ code to implement the code that acts on receiving a "Hello()" message, whereas the ProtocolParent requires your C++ code to implement the "World()" handler. IPDL generates boilerplate code to ''send'' these messages, but it has no idea what you want to do upon ''receiving'' them.
 
'''NOTE''': if you don't implement these functions, libxul will not link.
 
Now we'll make these skeletons do something useful. Take the code marked "// Header contents" in the ProtocolChild.h header and put it in a file called <code>ipc/test-harness/TestChild.h</code>. Rename "ActorImpl" to "TestChild," and make the constructor and destructor public. Put it inside the mozilla::test namespace. Next, take the code marked "// C++ file contents", put it in a file called <code>ipc/test-harness/TestChild.cpp</code>, and s/ActorImpl/TestChild/g again. Finally, repeat for the ProtocolParent.h header, creating TestParent.h and .cpp files.
 
As mentioned above, the existing test-harness calls into <code>TestParent::DoStuff</code> when it has finished low-level initialization. Let's implement that method now.
 
void TestParent::DoStuff()
{
puts("[TestParent] in DoStuff()");
SendHello();
}
 
This code will print the string above to stdout, then send the "Hello()" message to the TestChild actor. When the TestChild actor receives that message, its <code>RecvHello()</code> method will be called. Let's next implement that. Change its skeleton definition to
 
nsresult TestChild::RecvHello()
{
puts("[TestChild] Hello, ");
SendWorld();
return NS_OK;
}
 
As you might guess, this will print "Hello, " to stdout and then send the "World()" message back to the TestParent. And, you got it, this will in turn cause the parent actor's <code>RecvWorld()</code> handler to be invoked. Let's finally implement that.
 
nsresult TestParent::RecvWorld()
{
puts("[TestParent] world!");
return NS_OK;
}
 
Now we're ready to compile and run the C++ code.
== Put it all together ==
Confirm
699
edits

Navigation menu