简体   繁体   中英

Register a “Hello World” DBus service, object and method using Python

I'm trying to export a DBus service named com.example.HelloWorld , with an object /com/example/HelloWorld , and method com.example.HelloWorld.SayHello that prints "hello, world" if the method is called using

dbus-send --system --type=method_call --dest=com.example.HelloWorld /com/example/HelloWorld com.example.HelloWorld.SayHello

So my question is how do you make a simple DBus service with a single method that prints "hello, world" (on its own stdout).

When using dbus-python the following setup for exporting a D-Bus service works:

import gobject
import dbus
import dbus.service

from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)


OPATH = "/com/example/HelloWorld"
IFACE = "com.example.HelloWorld"
BUS_NAME = "com.example.HelloWorld"


class Example(dbus.service.Object):
    def __init__(self):
        bus = dbus.SessionBus()
        bus.request_name(BUS_NAME)
        bus_name = dbus.service.BusName(BUS_NAME, bus=bus)
        dbus.service.Object.__init__(self, bus_name, OPATH)

    @dbus.service.method(dbus_interface=IFACE + ".SayHello",
                         in_signature="", out_signature="")
    def SayHello(self):
        print "hello, world"


if __name__ == "__main__":
    a = Example()
    loop = gobject.MainLoop()
    loop.run()

The example is modified from your code with how the mainloop is setup for dbus-python with the following lines:

from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)

The mainloop is started after the service has been initialized in the last section of the example:

if __name__ == "__main__":
    a = Example()
    loop = gobject.MainLoop()
    loop.run()

The full example above can be called by calling dbus-send like so:

dbus-send --session --print-reply --type=method_call --dest=com.example.HelloWorld /com/example/HelloWorld com.example.HelloWorld.SayHello.SayHello

Note that this line is also modified from your question by specifying --session and not --system , and that the way to specify what method to call is to append the method name to the end of the interface and thus we have the double SayHello part there. If that was not intended, you can remove the added SayHello from the interface when exporting your method in the service like this:

# only 'IFACE' is used here
@dbus.service.method(dbus_interface=IFACE,
                     in_signature="", out_signature="")

And then the service can be called like so:

dbus-send --session --print-reply --type=method_call --dest=com.example.HelloWorld /com/example/HelloWorld com.example.HelloWorld.SayHello

Also see eg How to use the existing services in DBus? for more examples of minimal service and client code, and Role of Mainloops, Event Loops in DBus service for some info about the mainloop stuff.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM