linux下的dbus分析

狂风中的少年 提交于 2019-12-06 07:37:29

原文链接点击打开链接

简单的客户端服务端程序示例

        服务端只提供一种方法,add 需要两个double型的参数并把相加的结果用double型返回

        客户端将用proxy对象来代理服务器,同时也使用proxy对象来使用add方法

简单的服务端程序

        这个服务端会运行10秒然后自动关闭

服务端程序概述

        对于服务端程序我们做了哪些事

        1 包含需要的头文件

        2 初始化dbus-cxx库

        3 创建一个调度来管理线程,程序超时和监视I/O

        4 创建一个连接来连上D-Bus 节点

        5 询问在总线上要连接的程序的名字(即绑定服务端程序名和节点)

        6 在总线上创造一个对象

        7 添加一个叫add的方法给创建的对象

        8 等待连接调用

服务端示例代码

        稍后会分步解析

/***************************************************************************
* Copyright (C) 2007,2010 by Rick L. Vinyard, Jr. *
* rvinyard@cs.nmsu.edu *
* *
* This file is part of the dbus-cxx library. *
* *
* The dbus-cxx library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* version 3 as published by the Free Software Foundation. *
* *
* The dbus-cxx library is distributed in the hope that it will be *
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this software. If not see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include <dbus-cxx.h>
#include <unistd.h>
double add( double param1, double param2 ) { return param1 + param2; }
int main()
{
int ret;
DBus::init(); //初始化DBUS
DBus::Dispatcher::pointer dispatcher = DBus::Dispatcher::create(); //创建DBUS调度
DBus::Connection::pointer conn = dispatcher->create_connection(DBus::BUS_SESSION);//在调度上创建连向节点的连接
ret = conn->request_name( "dbuscxx.quickstart_0.server", DBUS_NAME_FLAG_REPLACE_EXISTING );//绑定服务端程序和节点
if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) return 1;
//create an object on us
DBus::Object::pointer object = conn->create_object("/dbuscxx/quickstart_0"); //创建一个服务端实例
//add a method that can be called over the dbus
object->create_method<double,double,double>("dbuscxx.Quickstart", "add", sigc::ptr_fun(add) ); //在实例上创建方法
sleep(10);
return 0;
}

服务端程序分步讨论

首先包含我们自己的main函数文件的头文件即#include <dbus-cxx.h>

之后定义一个函数作为服务端的工作负载。这个函数将是调用dbus add方法时将要调用的实际函数,所以要以接近实际作用来命名我们的函数,但是要注意:函数在程序中的实际名字和在DBUS服务端的名字不是一定要一样的。

初始化dbus-cxx库

在我们利用我们写的dbus-cxx做任何事情之前我们必须要调用库中的init()函数

DBus::init();

创建一个管理调度

创建一个管理调度带来处理进出的消息。处理进出的消息是十分繁琐的,调度类为我们处理了其中的大多数

DBus::Dispatcher::pointer dispatcher = DBus::Dispatcher::create();

创建一个连向节点的连接

有了调度之后就要创建一个连向节点的连接

DBus::Connection::pointer conn = dispatcher->create_connection(DBus::BUS_SESSION);

为我们的程序在总线上申请一个名字

接下来,我们需要申请一个名字,这个名字可以在总线上为我们的程序提供一个身份标识,这个地方需要检查一下错误

ret = conn->request_name( "dbuscxx.quickstart_0.server", DBUS_NAME_FLAG_REPLACE_EXISTING );
if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) return 1;


在总线上创建一个实例

现在我们的应用在总线上有名字了,我们还需要创建一个带路径的实例

DBus::Object::pointer object = conn->create_object("/dbuscxx/quickstart_0");

将名为add的方法添加到我们刚刚创建的实例上

我们将为我们的刚刚创建的对象添加一个名为add的方法。这里的add方法的实际功能是之前定义的具体的函数实现的且这里的名字不必和刚刚定义的具体的函数同名,但此处我们写同名。我们必须将这个添加至接口中。并且D-Bus规范要求接口名称必须至少包含一个字符,所以这里我们使用dbuscxx.Quickstart作为接口名。实际上,我们在D-Bus上创建了一个虚拟对象,并且可以选择使用C ++类方法或普通函数来提供它们的功能。

object->create_method<double,double,double>("dbuscxx.Quickstart", "add", sigc::ptr_fun(add) );

等待传入的调用

最终我们需要等待传入的调用。我们在主函数中休眠10s,并且调度会在调度线程中被处理。


客户端程序

概述

1 包含头文件

2 初始化dbus-cxx库

3 创建一个调度用来管理线程,超时和IO监视

4创建一个连向dbus节点的连接

5 创建一个代理对象来连接服务端的quickstart_0 对象

6 为刚刚创建的对象创建一个add方法的代理

7调用刚刚创建的方法代理

8打印结果

/***************************************************************************
* Copyright (C) 2007,2010 by Rick L. Vinyard, Jr. *
* rvinyard@cs.nmsu.edu *
* *
* This file is part of the dbus-cxx library. *
* *
* The dbus-cxx library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* version 3 as published by the Free Software Foundation. *
* *
* The dbus-cxx library is distributed in the hope that it will be *
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this software. If not see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include <dbus-cxx.h>
#include <iostream>
int main()
{
dispatcher = DBus::Dispatcher::create();
connection = dispatcher->create_connection( DBus::BUS_SESSION );
//create an object proxy, which stands in for a real object.
//a proxy exists over the dbus
object = connection->create_object_proxy("dbuscxx.quickstart_0.server", "/dbuscxx/quickstart_0");
//a method proxy acts like a real method, but will go over the dbus
//to do its work.
= *(object->create_method<double,double,double>("dbuscxx.Quickstart","add"));
double answer;
answer = add_proxy( 1.1, 2.2 );
std::cout << "1.1 + 2.2 = " << answer << std::endl;
return 0;
}


客户端程序分步解析

同样首先要包含头文件

#include <dbus-cxx.h>
#include <iostream>


初始化dbus-cxx库

DBus::init();

创建调度

DBus::Dispatcher::pointer dispatcher = DBus::Dispatcher::create();

创建连向dbus节点的连接

DBus::Connection::pointer conn = dispatcher->create_connection(DBus::BUS_SESSION);

为应用申请一个名字

ret = conn->request_name( "dbuscxx.quickstart_0.server", DBUS_NAME_FLAG_REPLACE_EXISTING );
if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) return 1;


创建一个连向server's quickstart_0对象的代理对象

你们会注意到直到这点,代码才会区分服务端和客户端代码。

object = connection->create_object_proxy("dbuscxx.quickstart_0.server", "/dbuscxx/quickstart_0");

创建这个代理对象的时候必须用服务端申请的名字和路径

调用代理方法

double answer;
answer = add_proxy( 1.1, 2.2 );


打印结果

std::cout << "1.1 + 2.2 = " << answer << std::endl;
return 0;
}







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