-
Notifications
You must be signed in to change notification settings - Fork 1
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 toSkinSensorId
, -
A struct such as
struct skin_writer_attr
translates toclass SkinWriterAttr
, -
A function such as
skin_writer_copy_last_buffer()
translates toSkinWriter::copyLastBuffer()
, -
A function argument such as
struct skin_reader_callbacks *callbacks
translates toSkinReaderCallbacks &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, sincestd::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 .