2

I developed an Arduino library that have a method called "process". This method is a Void function and must be called inside the loop and most of the time the library handles everything by it self:

#include <HookNinja.h>

HookNinja hookninja;

void setup()
{}

void loop()
{
  hookninja.process();
}

The idea is to keep the user program a simple as possible. Sometimes "process" have some data to give back to the user so he can use it as he likes. A simple approach is not to make process void and make the user check for the return value of process:

void loop()
{
  someVariableType foo;
  foo = hookninja.process();
  if(foo) {
    //user defined things
  }
}

But the data returned by process could be anything, from an int to an array of Strings, only the user knows the return type, also this method seems not very elegant. Im not an expert of C++, for me the ideal solution will be an object oriented approach were the user pass a function to process that can be called from the library, but I have no idea how to do this in C++, something like:

void userFunction(type param) {
  //do something with param
}

void loop() {
  hookNinja.process(some how pass userFunction here)
}

1 Answer 1

4

A common solution would be to have the user provide a callback which takes no arguments and returns nothing. This is how attachInterrupt() works, so it may be the least surprising approach for your users. The user function can then get data from the rest of the program using globals.

If you really prefer passing an argument to the user function, the problem is you do not know the data type. The usual approach in plain C is to give it a “generic” pointer, and let the user cast it into a pointer specific for his data type. This is how functions like qsort() work:

HookNinja hookninja;

void userFunction(void *param) {
    someVariableType foo = * (someVariableType *) param;
    //do something with foo
}

void setup()
{
    hookninja.attachCallback(userFunction);
}

void loop() {
    someVariableType foo = something;
    hookNinja.process((void *) &foo);
}

A cleaner C++ approach could be to make you class a template that is specialized for the type of the user data:

HookNinja<someVariableType> hookninja;

void userFunction(someVariableType param) {
    //do something with param
}

void setup()
{
    hookninja.attachCallback(userFunction);
}

void loop() {
    someVariableType foo = something;
    hookNinja.process(foo);
}

But keep in mind that many Arduino users may not be familiar with templates.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.