Skip to content
Shahbaz Youssefi edited this page Oct 8, 2015 · 3 revisions

Skinware with C++11

Skinware is written in C, but it provides a C++11 interface as well. The C++11 interface just creates classes out of Skinware structs, allows lambda functions for callbacks and such.

While the C structs and functions use the underscore style, the C++ interface uses camelCase to avoid name clashes. The following rules hold in translating between the C names and their C++ equivalents.

  • A data type such as skin_sensor_id translates to SkinSensorId,

  • A struct such as struct skin_writer_attr translates to class SkinWriterAttr,

  • A function such as skin_writer_copy_last_buffer() translates to SkinWriter::copyLastBuffer(),

  • A function argument such as struct skin_reader_callbacks *callbacks translates to SkinReaderCallbacks &callbacks,

  • A callback such as

    int (*write)(struct skin_writer *writer, void *mem, size_t size, void *user_data)

    translates to

    std::function<int (SkinWriter &, void *, size_t)>

    The user_data pointer is not provided in the C++11 version, since std::function can already contain closures.

Additionally, each class SkinX, containing a pointer to struct skin_x, contains an isValid() function that tells whether that pointer is NULL or not.

It is important to know that the Skin class, corresponding to struct skin does not call the skin_init() and skin_exit() functions (Skin::init() and Skin::exit() in the C++ version) in its constructor and destructor. This is because these operations require URT to be initialized. If left to constructor and destructor, they are very likely to be called before urt_init() or after urt_exit() is called. You should therefore remember to call those functions as you would in the C version.

Writing a Skinware application in C++, one could still do the URT way, even though the code would obviously never be used in kernel space, just to get the parameter and signal handling done by URT.

With this information in mind, writing C++11 applications is trivial knowing the C API. I will end this tutorial with an example in C and its equivalent in C++.

static int calc_sum(struct skin_sensor *sensor, void *d)
{
    unsigned int *sum = d;
    *sum += skin_sensor_get_response(s);
    return SKIN_CALLBACK_CONTINUE;
}

/* later */
while (!interrupted)
{
    unsigned int sum = 0, count = 0;

    /* connect to newly attached drivers and disconnect from removed drivers */
    skin_update(skin, &tattr);
    /* start operation of newly attached drivers */
    skin_resume(skin);

    /* find the sum of all sensors on the skin */
    skin_for_each_sensor(skin, calc_sum, &sum);
    count = skin_sensor_count(skin);
    if (count == 0)
        urt_out("No sensors in the skin\n");
    else
        urt_out("Average skin response is: %f\n", sum / (float)count);

    urt_sleep(interval_ms * 1000000ll);
}

In the above example, the average response from the skin is printed periodically. The following is the equivalent C++11 version:

while (!interrupted)
{
    unsigned int sum = 0, count = 0;

    /* connect to newly attached drivers and disconnect from removed drivers */
    skin.update(tattr);
    /* start operation of newly attached drivers */
    skin.resume();

    /* find the sum of all sensors on the skin */
    skin.forEachSensor([&](SkinSensor s){
                sum += s.getResponse();
                return SKIN_CALLBACK_CONTINUE;
            });
    count = skin.sensorCount();
    if (count == 0)
        urt_out("No sensors in the skin\n");
    else
        urt_out("Average skin response is: %f\n", sum / (float)count);

    urt_sleep(interval_ms * 1000000ll);
}

Next: See more .

Clone this wiki locally