【dbux-cxx】简介及例程

简介

D-Bus是一种高级的进程间通信机制,它由freedesktop.org项目提供,使用GPL许可证发行。D-Bus最主要的用途是在Linux桌面环境为进程提供通信,同时能将Linux桌面环境和Linux内核事件作为消息传递到进程。D-Bus的主要概念为总线,注册后的进程可通过总线接收或传递消息,进程也可注册后等待内核事件响应,例如等待网络状态的转变或者计算机发出关机指令。D-Bus已被大多数Linux发行版所采用,开发者可使用D-Bus实现各种复杂的进程间通信任务。

注意,dbus是一个协议,任何人只要按照这个协议就可以和其他符合协议的程序进行通信。官方实现是 libdbus,包含 dbus-monitor等调试命令程序;也还有其他版本的实现,比如systemd库的sd-bus,新版本glib库的GDBus libdbus库直接使用很晦涩难懂,所以有多基于libdbus的封装,称为 dbus binding,比如qt的QtDBus。

有些dbus实现就直接从头到尾自己实现协议,并提供api封装,和libdbus没有关系,比如目前引入的dbus-cxx库

参考资料

各种dbus binding
dbus-cxx官方网站

环境配置

参考此博文

例程

官方文档例程

例程来自官方文档例程,在此我只是把注解都添加了上去,并且添加了多个method。
dbus_cxx_server.cpp

#include <dbus-cxx.h>
#include <unistd.h>
 
 /*
We will define a function that will be our workhorse on the server side.
This function will be the actual function that will be called when the dbus add method is invoked,
so we will name our function similarly.
But, note that the actual name of the function in our program and the name in our dbus server do not have to match.
*/
double add( double param1, double param2 )      { return param1 + param2; }
double sub( double param1, double param2 )      { return param1 - param2; }
double mul( double param1, double param2 )      { return param1 * param2; }
double divv( double param1, double param2 )      { return param1 / param2; }
int main()
{
  //Now, we will create a dispatcher(调度) to handle incoming and outgoing messages.
  //Handling incoming and outgoing messages can be messy and the Dispatcher class handles much of this for us.
      std::shared_ptr<DBus::Dispatcher> dispatcher = DBus::StandaloneDispatcher::create();  //standalone表示独立
 
  //Now that we have a dispatcher we need to create a connection to the session bus.
      std::shared_ptr<DBus::Connection> conn = dispatcher->create_connection(DBus::BusType::SESSION);
 
  //Next, we need to request a name that will identify our application on the session bus.
      if( conn->request_name( "dbuscxx.quickstart_0.server",    DBUSCXX_NAME_FLAG_REPLACE_EXISTING ) != DBus::RequestNameResponse::PrimaryOwner )
          return 1;
 
  //Now that our application has a name on the bus we need to add an object with it's path.
      std::shared_ptr<DBus::Object> object = conn->create_object("/dbuscxx/quickstart_0",       DBus::ThreadForCalling::DispatcherThread);
 
  //We will now create a method named add for our object.
  //The functionality of the method will be provided by the function we declared above also named add().
  //We must add this to an interface,
  //and the D-Bus specification required that interface names must contain at least one . (period) character so we will use the interface name "dbuscxx.Quickstart".
      object->create_method<double(double,double)>("dbuscxx.Quickstart", "add",         sigc::ptr_fun(add));
      object->create_method<double(double,double)>("dbuscxx.Quickstart", "sub", sigc::ptr_fun(sub));
      object->create_method<double(double,double)>("dbuscxx.Quickstart", "mul", sigc::ptr_fun(mul));
      object->create_method<double(double,double)>("dbuscxx.Quickstart", "divv", sigc::ptr_fun(divv));  //这个名字是div的话会出现重载问题
/*
    sigc::ptr_fun(T_return(* func)(T_args...))
    Creates a functor of type sigc::pointer_functor which wraps an existing non-member function.
*/
 
      sleep(10000);
 
      return 0;
}


dbus_cxx_client.cpp

#include <dbus-cxx.h>
#include <iostream>
 
int main()
{
  //Create a dispatcher to manage threads, timeouts and I/O watches
      std::shared_ptr<DBus::Dispatcher> dispatcher;
      dispatcher = DBus::StandaloneDispatcher::create();
 
  //Create a connection to the D-Bus session bus
      std::shared_ptr<DBus::Connection> connection;
      connection = dispatcher->create_connection( DBus::BusType::SESSION );
 
  //create an object proxy, which stands in for a real object.(stand in:替身)
  //a proxy exists over the dbus
      std::shared_ptr<DBus::ObjectProxy> object;
      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.
      DBus::MethodProxy<double(double,double)>& add_proxy
    = *(object->create_method<double(double,double)>("dbuscxx.Quickstart","add"));
      DBus::MethodProxy<double(double,double)>& sub_proxy
    = *(object->create_method<double(double,double)>("dbuscxx.Quickstart","sub"));
      DBus::MethodProxy<double(double,double)>& mul_proxy
    = *(object->create_method<double(double,double)>("dbuscxx.Quickstart","mul"));
      DBus::MethodProxy<double(double,double)>& div_proxy
    = *(object->create_method<double(double,double)>("dbuscxx.Quickstart","divv"));
  double answer;
      answer = add_proxy( 1.1, 2.2 );
      std::cout << "1.1 + 2.2 = " << answer << std::endl;
      answer = sub_proxy( 1.1, 2.2 );
      std::cout << "1.1 - 2.2 = " << answer << std::endl;
      answer = mul_proxy( 12300.1, 36.2 );
      std::cout << "12300.1 * 36.2 = " << answer << std::endl;
      answer = div_proxy( 9.1, 3.2 );
      std::cout << "9.1 / 3.2 = " << answer << std::endl;
 
      return 0;
}


Makefile

.PHONY:clean
LD_LIBRARY_PATH:= /home/minshilzm/dbux-cxx/dbus-cxx-2.3.0/build:/home/minshilzm/libsigc++-3.0.0/__install/lib

CXXFLAG         = -std=c++17 -O3
PKGFLAG         = `pkg-config --cflags --libs dbus-cxx-2.0`

SERVER_SRC      = dbus_cxx_server.cpp
CLIENT_SRC      = dbus_cxx_client.cpp

SERVER_TARGET   = dbus_cxx_server
CLIENT_TARGET   = dbus_cxx_client

all: $(SERVER_TARGET) $(CLIENT_TARGET)

$(SERVER_TARGET):$(SERVER_SRC)
        g++ $(CXXFLAG)  $(SERVER_SRC) -o $(SERVER_TARGET) $(PKGFLAG)
$(CLIENT_TARGET):$(CLIENT_SRC)
        g++ $(CXXFLAG) $(CLIENT_SRC) -o $(CLIENT_TARGET) $(PKGFLAG)
clean:
        rm $(SERVER_TARGET) $(CLIENT_TARGET)


make完之后要在环境变量配置动态库路径,我用的是bash,所以有:
(1)vi ~/.bashrc
(2)添加
export LD_LIBRARY_PATH=/home/minshilzm/dbux-cxx/dbus-cxx-2.3.0/build:/home/minshilzm/libsigc+±3.0.0/__install/lib:$LD_LIBRARY_PATH

export PKG_CONFIG_PATH=/home/minshilzm/libsigc+±3.0.0/__install/lib/pkgconfig:$PKG_CONFIG_PATH

运行结果

在这里插入图片描述

最后这个div咋回事还在找原因…

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值