Page tree
Skip to end of metadata
Go to start of metadata

CommonAPI C++ and bindings have been moved to github, see overview at https://github.com/orgs/GENIVI/teams/someip/repositories and see also the CommonAPI C++ homepage at http://genivi.github.io/capicxx-core-tools/. Please make sure that you use code generators and runtime libraries with the same version by getting the code generator binaries from capicxx-core-tools/releases repository, capicxx-dbus-tools/releases repository and capicxx-someip-tools/releases repository. Otherwise you could get same strange compilation errors. Please note that a newer version of this wiki page can be accessed via capicxx-core-tools/wiki repository.

Valid for CommonAPI 3.1.3 and vsomeip 1.3.0

Step 1: Preparation / Prerequisites

The following description is based on CommonAPI 3.1.3 and assumes that you use a standard Linux distribution (I tested it with Xubuntu 14.04) and that you have installed git and (CMake >=2.8).

Step 2: Build the CommonAPI Runtime Library

Start with fetching the source code of CommonAPI, e.g. with:

Clone CommonAPI Repositories

The CommonAPI runtime library can now be built without any other dependencies:

Build CommonAPI

The output in your console should be similar to the extract of my output that it is the window above. Do not doubt when you see in your results that Doxygen or asciidoc is not found; it is only needed for the generation of the documentation. The package 'automotive-dlt' is only needed in case you want to get DLT log messages (see http://projects.genivi.org/diagnostic-log-trace/home). As shown in the last two lines you should find libCommonAPI.so in your build directory.

The CommonAPI runtime library can be installed to /usr/local (or any other directory if you set the installation prefix) by calling make install. But I assume that in most of the cases this is not wanted; therefore this description explains the procedure completely without any installations.

Step 3: Build the CommonAPI D-Bus Runtime Library

Start again with cloning the source code of CommonAPI-D-Bus: 

Clone CommonAPI D-Bus

The D-Bus runtime library cannot be built without further preparations. The reason is that CommonAPI-D-Bus doesn't use the standard libdbus library and needs a patched version. That means that you must first download, patch and build libdbus before the CommonAPI D-Bus runtime can be built. Let's start (3 of 10 minutes have already passed (smile)). Get and unpack the actual libdbus library:

Get libdbus

 I discarded the output in the console. Now apply the patches in the CommonAPI D-Bus source directory:

Patch libdbus

 At the moment there are three libdbus patches provided. Two of these patches provide additional functions which will be called from CommonAPI.

Please check if all these patches could be applied successfully. I tested it with D-Bus 1.6.x and 1.8.x. For other versions I cannot guarantee that the patches work. If necessary updated patch versions will be provided for D-Bus > 1.8.x.

 Now build libdbus with autotools and check if the so library has been created in the .libs-directory.

Build libdbus

Build libdbus with autotools. Otherwise you will miss some necessary files when you try to buld CommonAPI D-Bus.

 Now it is possible to build the CommonAPI runtime library. Please note that you only use the uninstalled versions of CommonAPI and libdbus. First create the build directory and change to the build directory:

Create Build Directory for CommonAPI D-Bus

 For the next step add the path to your D-Bus directory to the actual PKG_CONFIG_PATH environment variable, start CMake and call make as usual:

Build CommonAPI D-Bus

If everything was successful (it should be!) you should find libCommonAPI-DBus.so in your build directory. Make sure that there are no empty spaces in the path of your working directory.

Step 4: Write the Franca file and generate code

After all these preparations we start seriously to write a true CommonAPI application (more precisely two applications). We want to write one service which offers the method sayHello and one client which calls this method. For CommonAPI services the description of offered interfaces is done by means of Franca IDL. Don't worry if you don't know Franca IDL, you will learn it very fast.

First create some directories and open a new empty ASCII file with the name HelloWorld.fidl:

Create Project Directories

 Now create the following interface:

HelloWorld.fidl

Ready! A service which instantiates the interface HelloWorld provides the function sayHello which can be called. The next step is to generate code. For that we need the code generators. We copy them into the new subdirectory cgen of our project directory:

Get Code Generators

Now you find the executables of the code generators in cgen/commonapi-generator and cgen/commonapi_dbus_generator, respectively. There are four versions (Linux, Windows and 64bit variants). Type uname -m if you don't know if you have a 32bit or 64bit version of Linux (you get i686 or x86_64). For the further description we assume that you have the 32bit version.

Do not complain about details, such as that you have to call chmod or that the names contain sometimes underscores and sometimes hyphen. It will change in future versions.

Finally you can generate code (CommonAPI code with the commonapi-generator and CommonAPI D-Bus code with the commonapi-dbus-generator):

Generate Code

If everything worked, the generated code will be in the new directory src-gen. The option -sk generates a default implementation of your interface instance in the service.

Step 5: Write the client and the service application

Now we can start to write the Hello World application. Create new subdirectories src and build in the project directory and change to src.

Create src and build directories

Now we have to create 4 files: The client code (HelloWorldClient.cpp), one file for the main-function of the service (HelloWorldService.cpp) and 2 files (header and source) for the implementation of the generated skeleton for the stub (we call it HelloWorldStubImpl.hpp and HelloWorldStubImpl.cpp).

Let's begin with the client. Create a new file HelloWorldClient.cpp with the editor of your choice and type:

HelloWorldClient.cpp

At the beginning of each CommonAPI application it is necessary to get a pointer to the generic runtime object. The runtime is necessary to create proxies and stubs. A client application has to call functions of an instance of an interface in the service application. In order to be able to call these functions we must build a proxy for this interface in the client. The interface name is the template parameter of the buildProxy method; furthermore we build the proxy for a certain instance; the instance name is the second parameter in the buildProxy method. In principle there is the possibility to distinguish between instances in different so-call domains (first parameter), but we don't want to discuss this in depth at the moment and take always the domain "local".

The proxy provides the API function isAvailable; if the we start the service first then isAvailable returns always true. It is also possible to register a callback which is called when the service becomes available; but we try to keep it here as simple as possible.

Now we call the function sayHello which we have defined in our fidl-file. The function has one in-parameter (string) and one out-parameter (also string). Have a look into HelloWorldPorxy.hpp to get the information how exactly the function sayHello must be called. Here it is important to know that it is possible to call the synchronous variant of this function (what we do here) or to call the asynchronous variant (sayHelloAsync) which is slightly more complicated. One return value is the so-called CallStatus, which gives us the information if the call was successful or not. Again, to keep it simple we do not check the CallStatus and hope that everthing worked fine.

We continue now to write the service. Create a new file HelloWorldService.cpp:

HelloWorldService.cpp

The main function of the service is even simpler as the main function of the client because the implementation of the interface functions is in the stub implementation. Again we need the pointer to the runtime environment; then we instantiate our implementation of the stub and register this instance of the interface by calling registerService with an instance name. The service shall run forever and answer to function calls until it becomes killed; therefore we need the while loop at the end of the main function.

At the end we need the stub implementation; we realize it by creating a stub-implementation class which is inherited from the stub-default implementation. The header file is:

HelloWorldStubImpl.hpp

The  implementation is in the cpp-file:

HelloWorldStubImpl.cpp

If the function sayHello is called it gets the name (which is supposed to be the name of the developer of this application) and returns it with an added "Hello" in front. The return parameter is not directly the string as it is defined in the fidl-file; it is a standard function object with the return parameters as in-parameters. The reason for this is to provide the possibility to answer not synchronously in the implementation of this function but to delegate the answer to a different thread.

Step 6: Build and run

Since you must have installed CMake in order to build the CommonAPI runtime libraries, the fastest way to compile and build our applications is to write a simple CMake file. Create a new file CMakeLists.txt directly in the project directory:

CMakeLists.txt

As include paths we need the include directories of CommonAPI and bindings and D-Bus; the directory of the generated code must be also added. We link everything together and do not discuss here questions concerning the configuration with different bindings. Therefore we tell CMake where to find the CommonAPI libraries and libdbus (replace the absolute paths with the paths on your machine). At the end we build two executables, one for the service and one for the client.

Now call CMake (remember that we created the build directory before:

Build everything

Your output should look similiar. In the build direcory there should be two executables now: HelloWorldClient and HelloWorldService.

And start:

Start
  • No labels

3 Comments

  1. please note there is a shell script available at [https://github.com/gunnarx/build-common-api-cpp-native/blob/master/build-commonapi.sh] which is automating the described steps above.

    Thanks to Gunnar Andersson (old account) for providing it!

  2. I have a question about this tutorial.

    I am under studying a function for navigation using CommonAPI C++ D-Bus.

    So I did Step.1~Step5.

    But there is a problem during Step.6 Build and run.

    Build error happened at HelloWorldDBusStubAdapter.cpp.o.

    (If I comment HelloWorldDBusStubAdapter.cpp.o file out, there is no problem.)

     

    Can you help me about this build error?.

     

    bmk@bmk-VirtualBox:~/work/project/build$ make

    [ 10%] Building CXX object CMakeFiles/HelloWorldService.dir/src/HelloWorldService.cpp.o

    [ 20%] Building CXX object CMakeFiles/HelloWorldService.dir/src/HelloWorldStubImpl.cpp.o

    [ 30%] Building CXX object CMakeFiles/HelloWorldService.dir/src-gen/v1_0/commonapi/HelloWorldDBusStubAdapter.cpp.o

    In file included from /home/bmk/work/project/src-gen/v1_0/commonapi/HelloWorldDBusStubAdapter.cpp:11:0:

    /home/bmk/work/project/src-gen/v1_0/commonapi/HelloWorldDBusStubAdapter.hpp:50:28: error: ‘StubAttributeTable’ in namespace ‘CommonAPI::DBus’ does not name a type

         const CommonAPI::DBus::StubAttributeTable& getStubAttributeTable();

    /home/bmk/work/project/src-gen/v1_0/commonapi/HelloWorldDBusStubAdapter.hpp:80:22: error: ‘StubAttributeTable’ in namespace ‘CommonAPI::DBus’ does not name a type

         CommonAPI::DBus::StubAttributeTable stubAttributeTable_;

    ...

    ...

     

     

    1. Don't use the comment section as a support channel please.  It will be a mess.  Beopmo KIM - your question was already sent to the IPC mailing list.   And if you have a confirmed bug, please write it in this bug tracker|

      I will delete my other comments to clean up the page.