My C++ wrapper for D-BUS

P. Durante shackan at gmail.com
Fri Sep 16 04:27:21 PDT 2005


Hi Murray, hi David,
thanks a lot for your answers, I didn't even remember sending you that
email at first. Just some toughts:

about boost, I've liked using boost for my software, but after some tought I
preferred writing my own (compatible with boost::shared_ptr at least
as long as my code is concerned), here it is:

http://svn.berlios.de/viewcvs/bluetool/trunk/lib/common/include/common/refptr.h
http://svn.berlios.de/viewcvs/bluetool/trunk/lib/common/include/common/refptr_impl.h
http://svn.berlios.de/viewcvs/bluetool/trunk/lib/common/include/common/refcnt.h

it's UGLY, but it's just my first attempt at writing a shared
reference-counting ptr.

>DBusHandlerResult HandshakeHandler::HandleMessage(/*{{{*/
>   Handshake_ptr handshake,
>   dbus::Message_ptr message)
>{
> MIDASYNC_TRACER();
>
> const string member = message->Member();
>
> if (member == "GetProperties")
>   GetProperties(handshake, message);

That's a bit boring and error prone as soon as you try to change your
dbus methods, I automated this a bit with a macro, register_method,
here's just an example to see how it works:

#define COOL_THING_IFACE 'org.designfu.coolness'
#define COOL_THING_PATH  '/org/designfu/coolthing'
#define COOL_ERROR	 'org.designfu.coolness.error'

class CoolThing :
	public DBus::LocalInterface,
	public DBus::LocalObject
{
public:
	CoolThing();

	// ~CoolThing();
	// object path is automatically unregistered
	// when this object is deleted

public:
	/*	dbus methods
	*/
	void DoSomething	( const DBus::CallMessage& );
	void DoSomethingCool	( const DBus::CallMessage& );

protected:
	/*	other stuff
	*/
		....
};

CoolThing::CoolThing() :
	DBus::LocalInterface( COOL_THING_IFACE ),
	DBus::LocalObject(
		COOL_THING_PATH,
		DBus::Connection::SystemBus()
	)
{
	register_method( CoolThing, DoSomething );
	register_method( CoolThing, DoSomethingCool );
}

/* the function below is called automagically by the c++ wrapper
 * when an appropriate method_call message arrives
 */
void CoolThing::DoSomething( const DBus::CallMessage& msg )
{
	try
	{
		/* parse message and perform action
		 * most of the time we don't double-check
		 * parameter type, since an exception is
		 * automatically thrown
		 */
		DBus::MessageIter ri = msg.r_iter();

		const char* echo = ri.get_string();

		DBus::ReturnMessage reply (msg);

		/* todo, this append() could be nicer,
		 * it just wraps the C api right now
		 */
		reply.append(	DBUS_TYPE_STRING, &(echo),
				DBUS_TYPE_INVALID
		)
		conn().send(reply);
	}
	catch( Dbg::Error& e ) //also std::exception or DBus::Error would do
	{
		DBus::ErrorMessage em (msg, COOL_ERROR, e.what());
		conn().send(em);
	}
}

void CoolThing::DoSomethingCool( const DBus::CallMessage& msg )
{
	// same as above..
}

It's not beautiful, but it helped me getting the job done quickly.

One more thing, I had to write my own mainloop, and my own timeouts
and file descriptor watches, don't know if it's a good idea(probably
not) or if better alternatives (apart from Qt and GLib, of course) are
already around.

> > To summarize: We have different objectives for our implementations and
> > as I hardly have time for the project I use my D-BUS wrappers in, I will
> > probably not be of much use... :-(
> 
Mine were written in about a week without ANY previous dbus knowledge,
I was really in a hurry since I had a schedule and writing some
bindings from scratch was not on that schedule ( I was assuming some
working bindings were already available, apparently I was wrong ), c++
bindings are quite needed imho and I hope someone will throw some time
and code at it.

btw, if anyone is interested..
http://svn.berlios.de/viewcvs/bluetool/trunk/lib/cbus/

regards,
Paul


More information about the dbus mailing list