# C++ - How to write a qimessaging service ¶

This document will teach you how to write your very own qimessaging service, so that your new shiny object can be used by other qimessaging services and clients, locally or remotely, and from many different programming languages.

## Limitations ¶

There are some restrictions on what you can do:

• Do not use class member data .
• Output parameters are not supported: you should not take pointers as arguments, or non-const references.
• Do not use methods in transmitted struct , as they will not be available in other languages: put the methods in an associated class .

To understand those restrictions, keep in mind that qimessaging is a middleware that knows how to transport data (like primitive types, structs, and containers of the above), and how to make calls to remote methods, signals and properties, but cannot mix the two.

Your service can be a simple class which is registered in the type system (see type registration ):



#include <qi/anyobject.hpp>

struct Mosquito
{
double yaw,theta,distance;
};
QI_TYPE_STRUCT(Mosquito, yaw, theta, distance)

class Cat
{
public:
void meow(int volume);
bool setTarget(const Mosquito& m);

qi::Property<float> hunger;
qi::Property<float> boredom;
qi::Property<float> cuteness;
qi::Signal<Mosquito> onTargetDetected;
};
QI_REGISTER_OBJECT(Cat, meow, setTarget, hunger, boredom, cuteness,
onTargetDetected);



Now your class and its types (Mosquito) are known by the type-system. If you don’t want to make a module, you can skip directly to the Manual way section.

You will then put this class in a module (like a library) that you will be able to load dynamically. You will also need to advertise a factory to be able to make a  Cat  out of this module, like this:



void registerCat(qi::ModuleBuilder* mb)
{
}
QI_REGISTER_MODULE("catsimulator", &registerCat);



Your module will be called  catsimulator  (must be the same name that you will put in your CMake file). You can now write a CMakeLists.txt and you’re done:



cmake_minimum_required(VERSION 2.8)
project(catsimulator)

find_package(qibuild)
find_package(qimodule)

qi_create_module(catsimulator
SRC
src/cat.cpp
DEPENDS
QI
)



Remember that the name you put in  qi_create_module  must be the same as the one in  QI_REGISTER_MODULE  . For more information about modules, see  qi::AnyModule  .

### Fully automated way ¶



qilaunch -n catsimulator --object catsimulator.Cat



qilaunch instantiates your service and registers it on the ServiceDirectory. It will forward its logs to the LogManager if present and will initialize breakpad to make a minidump when it crashes. You can stop it at any time with CTRL-C.

### Semi-automated way ¶

You can also instantiate your object manually and expose it on a session. In this example,  ApplicationSession  parses the command line arguments to find out what the user wants, i.e.:

• which type of session (listening or connected to a ServiceDirectory)

And then it initializes a session accordingly.



#include <qi/applicationsession.hpp>

int main(int argc, char** argv)
{
qi::ApplicationSession app(argc, argv);
app.start();
qi::SessionPtr session = app.session();

app.run();
}



### Manual way ¶

If you don’t want to use a module at all but simply make a binary that publishes your service, you can just do, similarly to the example above:



#include <qi/applicationsession.hpp>

int main(int argc, char** argv)
{
qi::ApplicationSession app(argc, argv);
app.startSession();
qi::SessionPtr session = app.session();

auto cat = boost::make_shared<Cat>();
session->registerService("CatService", cat);

app.run();
}



Then, you don’t need to use  qi_create_module  in your CMake file, you can just use  qi_create_bin  .

The session will keep a reference on cat until it is closed or CatService is unregistered.