# SoftBank Robotics documentation What's new in NAOqi 2.8?

# 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.

## Write your service

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)
    {
      mb->advertiseFactory<Cat>("Cat");
    }
    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`.

## Running your service

### Fully automated way

You can start your service by using qilaunch, like this:

    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.

For more information on qilaunch, read Using qilaunch.

### 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)
- on which address

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();

      session->loadService("catsimulator.Cat");

      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.

Glossary Site map Index Support Contact Legal Notices