DBUS客户端程序,发送一个信号,信号携带int型数据。信号的object path为"/test/signal/server",interface名为 "test.signal.Type",信号名为"Test"。接收端可以根据这三个属性来判断是否是想接收的信号。
使用dbus前要建立一个连接,通过这个连接连到dbus总线。DBusConnection *dbus_bus_get (DBusBusType type, DBusError *error) 函数就是建立连接用的。第一个参数为dbus连接类型,分为DBUS_BUS_SESSION(会话总线)和DBUS_BUS_SYSTEM(系统总线)。第二个参数用来返回错误消息。返回结果是与dbus建立的连接。
连接建立好了,为了方便使用需要给它起个名字,用dbus_bus_request_name()函数。
dbus_message_new_signal()用来创建一个信号。有个信号还需要往里添加数据。我把DBusMessageIter相当于一个数据容器指针。然后使用dbus_message_iter_init_append()将信号和数据指针挂上关系。然后往DBusMessageIter里挂数据,间接的往信号里放数据。再使用dbus_connection_send()把数据发出去,剩下的就等着接收端收了。
dbus_connection_send()表示发送消息,并且不接收返回。如果发送的消息需要回应,可使用dbus_connection_send_with_reply()函数。用法如下:
DBusPendingCall *pending_return;
if (!dbus_connection_send_with_reply(conn, msg, &pending_return, -1)) //发送后需要对方返回
{cout<<"Error in dbus_connection_send_with_reply\n";exit(1);
}if(pending_return == NULL)
{cout<<"pending return is NULL"<<endl;exit(1);
}
dbus_connection_flush(conn); //阻塞程序,直到传出消息队列为空
dbus_message_unref(msg); //减少DBusMessage的引用计数,如果计数为0,则释放消息
dbus_pending_call_block(pending_return); //阻塞,直到pending call完成DBusMessage *reply;
if ((reply = dbus_pending_call_steal_reply(pending_return)) == NULL) //获得返回消息
{cout<<"Error in dbus_pending_call_steal_reply"<<endl;exit(1);
}dbus_pending_call_unref(pending_return); //减少pending call的参考计数,如果计数达到0,则将其释放
char *s;
if (dbus_message_get_args(reply, &dbus_error, DBUS_TYPE_STRING, &s, DBUS_TYPE_INVALID))
//得到消息内容。DBUS_TYPE_STRING表示消息类型,DBUS_TYPE_INVALID终止列表。此处表示判断是否获得DBUS_TYPE_STRING类型的消息
{cout<<"get reply: "<<s<<endl;
}dbus_message_unref(reply);
发送程序示意图:
//dbusclient.cpp
#include <iostream>
#include <stdlib.h>
#include <dbus/dbus.h>
#include <unistd.h>
#include <strings.h>using namespace std;const int RES_SUCCESS = -1;
const int RES_FAILED = 0;int my_dbus_initialization(char const *_bus_name, DBusConnection **_conn, DBusBusType bustype)
{DBusError err;int ret;dbus_error_init(&err); //DBusError need init before use*_conn = dbus_bus_get(bustype, &err);if (dbus_error_is_set(&err)){cout<<"Connection error"<<endl;dbus_error_free(&err);return RES_FAILED;}ret = dbus_bus_request_name(*_conn, _bus_name, DBUS_NAME_FLAG_REPLACE_EXISTING, &err);if (dbus_error_is_set(&err)){cout<<"Request name error"<<endl;dbus_error_free(&err);return RES_FAILED;}if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret){cout<<"owner failed"<<endl;return RES_FAILED;}return RES_SUCCESS;
}int my_dbus_send_signal(DBusConnection *conn, uint32_t number)
{dbus_uint32_t serial = 0;DBusMessage *msg;DBusMessageIter args;msg = dbus_message_new_signal("/test/signal/server", //object name of the signal"test.signal.Type", //interface name of the signal"Test"); //name of signalif (NULL == msg){cout<<"Message Null";return RES_FAILED;}dbus_message_iter_init_append(msg, &args);if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT32, &number)){cout<<"Out of memory"<<endl;return RES_FAILED;}cout<<"send data: "<<number<<endl;if (!dbus_connection_send(conn, msg, &serial)){cout<<"out of memory"<<endl;dbus_message_unref(msg);return RES_FAILED;}dbus_connection_flush(conn);dbus_message_unref(msg);return RES_SUCCESS;
}int main(int argc, char** argv)
{DBusConnection *conn;if (RES_FAILED == my_dbus_initialization("test.signal.client", &conn, DBUS_BUS_SESSION)){exit(1);}cout<<"please input a number:";uint32_t number;cin>>number;my_dbus_send_signal(conn, number);return 0;
}
//编译命令:g++ -o dbusclient dbusclient.cpp -ldbus-1