DBUS发送数据程序1

纵饮孤独 提交于 2019-12-06 08:38:13

    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使用前需要初始化
    *_conn = dbus_bus_get(bustype, &err); //获得dbus连接
    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); //注册dbus名称
    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)
{
    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); //消息与数据指针挂上关系

    int my_age = 100;
    if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT32, &my_age)) //添加int型数据
    {
        cout<<"Out of memory"<<endl;
        return RES_FAILED;
    }
    cout<<"send data: "<<my_age<<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);
    }
    
    my_dbus_send_signal(conn);


    return 0;
}
 

//编译命令:g++ -o dbusclient dbusclient.cpp -ldbus-1

接收程序后续补充。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!