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 signal
if (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
来源:CSDN
作者:gdizcm
链接:https://blog.csdn.net/gdizcm/article/details/103610174