Question

Currently I have a number of sliders that are used to change image values. I am using the OpenCV track bar for the slider which has a callback to a different function for each of my sliders. I would like to have my sliders callback point to a single callback function and then use the user data to identify which track bar made the call.

Here is the documentation for the track bar

I am unsure what values i should be passing to void*, and also how to then retrieve this value form my callback function Below is an example of my track bar which compiles.

int ref = 1;
createTrackbar("Name","Window",0, 1, myFunc, &ref);

In my callback function I try and retrieve the value of ref.

void myFunc(int value, void *userdata)
{
    int val = *((int*)&userdata);
    cout << val << endl;
}

I had issues trying to convert the pointer back to an int, this is a solution i found online which gives me val as the address of ref.

int val = *((int*)&userdata);

This seems a lot of hassle, as i then have to get the value back form the address at val. Is there an easier way to do this?

Était-ce utile?

La solution

No, there is no simplier way. It's nessesary minimum for functionality you want.

Autres conseils

Passing a single variable which seems less hassle.

void cb_func(..., void *userdata) {
    int val = *static_cast<int *>(userdata);
}

Call it with:

cv_function_takes_callback(..., cb_func, static_cast<void *>(&val));

C++11 way of passing multiple variables.
You can pass references and even lambda functions.

type1 var1;
type2 var2;
auto lambda_no_capture = [](...) { ... };

typedef std::tuple<type1, const type2 &, decltype(lambda_no_capture)> tup_t;
tup_t tup(var1, var2, lambda_no_capture);

auto cb_func = [](..., void *userdata) -> void {
    tup_t &tup = *static_cast<tup_t *>(userdata);
    type1 var1 = std::get<0>(tup);
    decltype(auto) var2 = std::get<const type2 &>(tup); // requires c++14
    auto lambda_no_capture = std::get<2>(tup);
};

cv_function_takes_callback(..., cb_func, static_cast<void *>(&tup));

A few notes:

  • You can use auto var1 = std::get<0>(tup); but being explicit is better.

  • In case you are using auto with referenced variables, use const auto &var2 = std::get<1>(tup);. If you are not bound to C++11, decltype(auto) is what this is for.

  • Passing lambda functions to the callback functions seems cool but it is no different from using functions at global scope since they cannot have captured parameters.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top