dbus-cxx logo
calculator_server.cpp

This example is one part of three example applications that demonstrate client, server and watcher applications that use adapters and proxies generated by dbus-cxx-xml2cpp from a modified dbus introspection XML document.These three examples are:

This particular piece is the server that uses the generated Object derived class to provide an adapter interface for the Calculator class.

Here is the calculator class, which by itself knows nothing of dbus:

/***************************************************************************
* Copyright (C) 2009 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/>. *
***************************************************************************/
#ifndef CALCULATOR_H
#define CALCULATOR_H
#include <sigc++/sigc++.h>
#include <string>
#include <cstdint>
namespace Examples
{
class Calculator
{
public:
Calculator() { }
~Calculator() { }
double add( double a, double b );
double subtract( double a, double b );
double multiply( double a, double b );
double divide( double a, double b );
sigc::signal<void,std::string,std::string,double,double,double> signal_calculation();
uint64_t factorial( uint8_t n );
uint64_t fibonacci( uint8_t n );
uint64_t thue_morse( uint8_t n );
sigc::signal<void,std::string,uint64_t,uint8_t> signal_computation();
double pi();
void print_pi();
protected:
sigc::signal<void,std::string,std::string,double,double,double> m_signal_calculation;
sigc::signal<void,std::string,uint64_t,uint8_t> m_signal_computation;
uint64_t compute_factorial( uint8_t n );
uint64_t compute_fibonacci( uint8_t n );
uint64_t compute_thue_morse( uint8_t n );
};
}
#endif
/***************************************************************************
* Copyright (C) 2009 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 "calculator.h"
#include <iostream>
#include <cmath>
#include <unistd.h>
namespace Examples
{
double Calculator::add( double a, double b )
{
double result = a+b;
m_signal_calculation.emit( "add", "+", result, a, b );
return result;
}
double Calculator::subtract( double a, double b )
{
double result = a-b;
m_signal_calculation.emit( "subtract", "-", result, a, b );
return result;
}
double Calculator::multiply( double a, double b )
{
double result = a*b;
m_signal_calculation.emit( "multiply", "*", result, a, b );
return result;
}
double Calculator::divide( double a, double b )
{
double result = a/b;
m_signal_calculation.emit( "divide", "/", result, a, b );
return result;
}
sigc::signal< void, std::string, std::string, double, double, double > Calculator::signal_calculation()
{
return m_signal_calculation;
}
uint64_t Calculator::factorial( uint8_t n )
{
uint64_t result = compute_factorial( n );
m_signal_computation.emit( "factorial", result, n );
return result;
}
uint64_t Calculator::fibonacci( uint8_t n )
{
uint64_t result = compute_fibonacci( n );
m_signal_computation.emit( "Fibonacci", result, n );
return result;
}
uint64_t Calculator::thue_morse( uint8_t n )
{
uint64_t result = compute_thue_morse( n );
m_signal_computation.emit( "Thue-Morse", result, n );
return result;
}
sigc::signal< void, std::string, uint64_t, uint8_t > Calculator::signal_computation()
{
return m_signal_computation;
}
double Calculator::pi()
{
return M_PI;
}
void Calculator::print_pi()
{
std::cout << M_PI << std::endl;
}
uint64_t Calculator::compute_factorial( uint8_t n )
{
if ( n == 0 ) return 1;
return n * compute_factorial( n-1 );
}
uint64_t Calculator::compute_fibonacci( uint8_t n )
{
if ( n == 0 ) return 0;
if ( n == 1 ) return 1;
return compute_fibonacci( n-1 ) + compute_fibonacci( n-2 );
}
uint64_t Calculator::compute_thue_morse( uint8_t n )
{
if ( n == 0 ) return 0;
if ( n > 6 ) return 0;
uint64_t result, prev, neg, mask;
prev = compute_thue_morse( n-1 );
mask = ~( 0xFFFFFFFFFFFFFFFFULL << (int)pow(2,n-1) );
neg = ( ~prev ) & mask;
prev = prev << (int)pow(2,n-1);
result = prev | neg;
return result;
}
}

The adapter is generated with this command:

dbus-cxx-xml2cpp --xml calculator.xml --adapter -f

The modified introspection XML document is here:

<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node gen-namespace="DBus::Example" orig-namespace="Examples" cppname="Calculator" cppinclude="&quot;calculator.h&quot;" dest="dbuscxx.example.calculator.server" path="/dbuscxx/example/Calculator" >
<interface name="Calculator.Basic">
<method name="add">
<arg name="result" direction="out" type="d"/>
<arg name="a" direction="in" type="d"/>
<arg name="b" direction="in" type="d"/>
</method>
<method name="sub" cppname="subtract">
<arg name="result" direction="out" type="d"/>
<arg name="a" direction="in" type="d"/>
<arg name="b" direction="in" type="d"/>
</method>
<method name="mul" cppname="multiply">
<arg name="result" direction="out" type="d"/>
<arg name="a" direction="in" type="d"/>
<arg name="b" direction="in" type="d"/>
</method>
<method name="div" cppname="divide">
<arg name="result" direction="out" type="d"/>
<arg name="a" direction="in" type="d"/>
<arg name="b" direction="in" type="d"/>
</method>
<method name="pi">
<arg name="result" direction="out" type="d"/>
</method>
<method name="print_pi">
</method>
<signal name="calculation" accessor="signal_calculation()">
<arg name="op" type="s"/>
<arg name="opsym" type="s"/>
<arg name="result" type="d"/>
<arg name="a" type="d"/>
<arg name="b" type="d"/>
</signal>
</interface>
<interface name="Calculator.Computed">
<method name="factorial">
<arg name="result" direction="out" type="t"/>
<arg name="n" direction="in" type="y"/>
</method>
<method name="fibonacci">
<arg name="result" direction="out" type="t"/>
<arg name="n" direction="in" type="y"/>
</method>
<method name="thue_morse">
<arg name="result" direction="out" type="t"/>
<arg name="n" direction="in" type="y"/>
</method>
<signal name="computation" accessor="signal_computation()">
<arg name="algorithm" type="s"/>
<arg name="result" type="t"/>
<arg name="n" type="y"/>
</signal>
</interface>
</node>

Here is the generated adapter:

#ifndef __DBUS_ADAPTER_DBUS_EXAMPLE_CALCULATOR_H
#define __DBUS_ADAPTER_DBUS_EXAMPLE_CALCULATOR_H
#include <dbus-cxx.h>
#include "calculator.h"
namespace DBus {
namespace Example {
class CalculatorAdapter : public ::DBus::Object
{
protected:
CalculatorAdapter( Examples::Calculator* adaptee=NULL, const std::string& path="/dbuscxx/example/Calculator"):
m_adaptee(adaptee)
{
temp_method = this->create_method<double,double,double>( "Calculator.Basic", "add", sigc::mem_fun(*this, &CalculatorAdapter::add_adapter_stub_hhh) );
temp_method->set_arg_name( 0, "result" );
temp_method->set_arg_name( 1, "a" );
temp_method->set_arg_name( 2, "b" );
temp_method = this->create_method<double,double,double>( "Calculator.Basic", "sub", sigc::mem_fun(*this, &CalculatorAdapter::sub_adapter_stub_hhh) );
temp_method->set_arg_name( 0, "result" );
temp_method->set_arg_name( 1, "a" );
temp_method->set_arg_name( 2, "b" );
temp_method = this->create_method<double,double,double>( "Calculator.Basic", "mul", sigc::mem_fun(*this, &CalculatorAdapter::mul_adapter_stub_hhh) );
temp_method->set_arg_name( 0, "result" );
temp_method->set_arg_name( 1, "a" );
temp_method->set_arg_name( 2, "b" );
temp_method = this->create_method<double,double,double>( "Calculator.Basic", "div", sigc::mem_fun(*this, &CalculatorAdapter::div_adapter_stub_hhh) );
temp_method->set_arg_name( 0, "result" );
temp_method->set_arg_name( 1, "a" );
temp_method->set_arg_name( 2, "b" );
temp_method = this->create_method<double>( "Calculator.Basic", "pi", sigc::mem_fun(*this, &CalculatorAdapter::pi_adapter_stub_h) );
temp_method->set_arg_name( 0, "result" );
temp_method = this->create_method<void>( "Calculator.Basic", "print_pi", sigc::mem_fun(*this, &CalculatorAdapter::print_pi_adapter_stub_v) );
m_signal_adapter_calculation = this->create_signal<void,std::string,std::string,double,double,double>("Calculator.Basic","calculation");
m_signal_adapter_calculation->set_arg_name( 0, "op" );
m_signal_adapter_calculation->set_arg_name( 1, "opsym" );
m_signal_adapter_calculation->set_arg_name( 2, "result" );
m_signal_adapter_calculation->set_arg_name( 3, "a" );
m_signal_adapter_calculation->set_arg_name( 4, "b" );
if ( m_adaptee ) m_signal_adapter_connection_calculation = m_adaptee->signal_calculation().connect( *m_signal_adapter_calculation );
temp_method = this->create_method<uint64_t,uint8_t>( "Calculator.Computed", "factorial", sigc::mem_fun(*this, &CalculatorAdapter::factorial_adapter_stub_hh) );
temp_method->set_arg_name( 0, "result" );
temp_method->set_arg_name( 1, "n" );
temp_method = this->create_method<uint64_t,uint8_t>( "Calculator.Computed", "fibonacci", sigc::mem_fun(*this, &CalculatorAdapter::fibonacci_adapter_stub_hh) );
temp_method->set_arg_name( 0, "result" );
temp_method->set_arg_name( 1, "n" );
temp_method = this->create_method<uint64_t,uint8_t>( "Calculator.Computed", "thue_morse", sigc::mem_fun(*this, &CalculatorAdapter::thue_morse_adapter_stub_hh) );
temp_method->set_arg_name( 0, "result" );
temp_method->set_arg_name( 1, "n" );
m_signal_adapter_computation = this->create_signal<void,std::string,uint64_t,uint8_t>("Calculator.Computed","computation");
m_signal_adapter_computation->set_arg_name( 0, "algorithm" );
m_signal_adapter_computation->set_arg_name( 1, "result" );
m_signal_adapter_computation->set_arg_name( 2, "n" );
if ( m_adaptee ) m_signal_adapter_connection_computation = m_adaptee->signal_computation().connect( *m_signal_adapter_computation );
}
public:
typedef DBusCxxPointer<CalculatorAdapter> pointer;
static pointer create( Examples::Calculator* adaptee=NULL, const std::string& path="/dbuscxx/example/Calculator")
{ return pointer( new CalculatorAdapter(adaptee, path)); }
Examples::Calculator* adaptee() { return m_adaptee; }
void set_adaptee( Examples::Calculator* adaptee ) {
m_adaptee = adaptee;
m_signal_adapter_connection_calculation.disconnect();
if ( m_adaptee ) m_signal_adapter_connection_calculation = m_adaptee->signal_calculation().connect( *m_signal_adapter_calculation );
m_signal_adapter_connection_computation.disconnect();
if ( m_adaptee ) m_signal_adapter_connection_computation = m_adaptee->signal_computation().connect( *m_signal_adapter_computation );
}
void set_adaptee( Examples::Calculator& adaptee ) {
this->set_adaptee(&adaptee);
}
private:
Examples::Calculator* m_adaptee;
void check_adaptee() { if ( not m_adaptee) throw ::DBus::ErrorInvalidAdaptee::create(); }
double add_adapter_stub_hhh( double a, double b ) { this->check_adaptee(); return m_adaptee->add( a, b); }
double sub_adapter_stub_hhh( double a, double b ) { this->check_adaptee(); return m_adaptee->subtract( a, b); }
double mul_adapter_stub_hhh( double a, double b ) { this->check_adaptee(); return m_adaptee->multiply( a, b); }
double div_adapter_stub_hhh( double a, double b ) { this->check_adaptee(); return m_adaptee->divide( a, b); }
double pi_adapter_stub_h( ) { this->check_adaptee(); return m_adaptee->pi(); }
void print_pi_adapter_stub_v( ) { this->check_adaptee(); m_adaptee->print_pi(); }
sigc::connection m_signal_adapter_connection_calculation;
uint64_t factorial_adapter_stub_hh( uint8_t n ) { this->check_adaptee(); return m_adaptee->factorial( n); }
uint64_t fibonacci_adapter_stub_hh( uint8_t n ) { this->check_adaptee(); return m_adaptee->fibonacci( n); }
uint64_t thue_morse_adapter_stub_hh( uint8_t n ) { this->check_adaptee(); return m_adaptee->thue_morse( n); }
sigc::connection m_signal_adapter_connection_computation;
};
}
}
#endif

And here is the server application:

/***************************************************************************
* Copyright (C) 2009,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 "calculator_adapter.h"
#include <unistd.h>
int main()
{
int ret;
DBus::Connection::pointer conn = dispatcher->create_connection(DBus::BUS_SESSION);
// request a name on the bus
ret = conn->request_name( "dbuscxx.example.calculator.server", DBUS_NAME_FLAG_REPLACE_EXISTING );
if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) return 1;
Examples::Calculator calculator;
DBus::Example::CalculatorAdapter::pointer adapter = DBus::Example::CalculatorAdapter::create(&calculator);
conn->register_object( adapter );
std::cout << "Running" << std::flush;
for (int i=0; i < 20; i++)
{
std::cout << "." << std::flush;
sleep(1);
}
std::cout << std::endl;
return 0;
}

Generated on Sun Mar 19 2017 14:54:26 for dbus-cxx by doxygen 1.8.8