我正在尝试导出一个名为com.example.HelloWorld
的DBus服务,该服务带有一个对象/com/example/HelloWorld
和一个方法com.example.HelloWorld.SayHello
,如果使用调用该方法,该方法将显示“hello,world”
dbus发送--system --type = method_call --dest = com.example.HelloWorld/com/example/HelloWorld com.example.HelloWorld.SayHello
所以我的问题是,如何用一种打印“hello,world”(在其自己的stdout上)的方法制作一个简单的DBus服务。
最佳答案
使用dbus-python
时,以下用于导出D-Bus服务的设置有效:
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()
该示例是通过以下行代码为您设置的
dbus-python
设置mainloop的代码的一部分:from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)
在示例的最后一部分中,在初始化服务之后启动mainloop:
if __name__ == "__main__":
a = Example()
loop = gobject.MainLoop()
loop.run()
可以通过调用
dbus-send
来调用上面的完整示例,如下所示:dbus-send --session --print-reply --type=method_call --dest=com.example.HelloWorld /com/example/HelloWorld com.example.HelloWorld.SayHello.SayHello
请注意,也可以通过指定
--session
而不是--system
来从您的问题中修改此行,并且指定要调用的方法的方法是将方法名称附加到接口(interface)的末尾,因此我们在其中有双SayHello
部分。如果这不是故意的,则可以在服务中将方法导出时,从接口(interface)中删除添加的SayHello
,如下所示:# only 'IFACE' is used here
@dbus.service.method(dbus_interface=IFACE,
in_signature="", out_signature="")
然后可以像这样调用服务:
dbus-send --session --print-reply --type=method_call --dest=com.example.HelloWorld /com/example/HelloWorld com.example.HelloWorld.SayHello
另请参阅How to use the existing services in DBus?提供了最少的服务和客户端代码的更多示例,Role of Mainloops, Event Loops in DBus service提供了有关mainloop内容的一些信息。