.. _quickstart/cpp/services_wrapped: .. default-domain:: cpp ####################################################################### Quickstart: Handling Services with auto-generated Wrapper Code from C++ ####################################################################### .. contents:: This addition to the quickstart examples shows how to define a service provider in C++ by usinng auto-generated wrapper classes. It is intended for cases where a lot of code would need to be generated. .. warning:: Generally, the example given in :doc:`quickstart_cpp_services` is preferable and recommended to use, because the resulting code and API is easier to explain and understand than code based on auto-generated code, even if it is a bit longer. .. index:: pair: LN services; "wrapped" provider example in C++ Defining a "wrapped" service provider in C++ ============================================ Here is how the "wrapped" service provider class looks: .. literalinclude:: examples/quickstart/cpp/services_wrapped_api/provider.cpp :language: c++ :linenos: :emphasize-lines: 15,16,25,26,31,32 Initialization -------------- We start with the initialization of the provider class. The class is derived from two auto-generated classes named ``area_service::circle_area_base``, and ``area_service::ellipse_area_base``. These were auto-generated by :program:`ln_generate`, and included in :file:`ln_messages`. Lines 25 and 26 is the code which initializes the service provider class and its handlers for service message requests. Here, the service handler for the message definition ``area_service/circle_area`` is initialized with the name of the service, and the same happens with the service for ``area_service/ellipse_area``. The names of the handler methods are hard-coded and auto-generated from the message definitions. For the message name ``area_service/circle_area``, it is ``on_circle_area()``, and for ``area_service/ellipse_area``, ``on_ellipse_area()``. Handler Methods --------------- The handler method ``on_circle_area()`` is shown in lines 31 to 58. The Request Data Buffer ~~~~~~~~~~~~~~~~~~~~~~~ For each method, a buffer with the name ``data`` is passed, which has two members, ``req`` and ``resp``. This buffer has the purpose to hold the request parameter data, as well as the response data. Its type is of type ``area_service::circle_area_t``, which was auto-generated by :program:`ln_generate` from the message definition with the name "area_service/circle_area" - each slash in the message definition name is converted into a nested C++ namespace identifier. The type name ``area_service::circle_area_t`` is formed from the message definition that we use, ``"area_service/circle_area"``, by replacing each slach ("/") with a double-colon ("::"), and appending an "_t". This is a type that is auto-generated by :program:`ln_generate` from the message definitions when :program:`make` builds the header file :file:`ln_messages` as an intermediate target. This can also be described as ``data.req`` having the auto-generated type :cpp:member:`MESSAGE_DEF_NAMESPACE::SVMDEF_NAME::req`. Here, ``MESSAGE_DEF_NAMESPACE::SVMDEF_NAME`` is the meta-typename constructed from the name of the message definition with each slash ("/") replaced by a pair of colons ("::"). After that, the service handler can access the *request parameters* to the member fields of ``data.req``. In our case, this is ``data.req.radius``. The response data has to be places into the member fields of ``data.resp``, which is of type :cpp:member:`MESSAGE_DEF_NAMESPACE::SVMDEF_NAME::resp`. The method ``AreaServer::on_ellipse_area()`` works in the same way. Running the Service Provider ---------------------------- The remaining parts of the service provider class work as described in :doc:`quickstart_cpp_services`. .. Tip:: A more detailed example for the "wrapped" API can be found in the chapter :doc:`user_guide_cpp_wrapped-api`.