Мы до сих пор не знаем, что не работает для вас , но я предоставлю некоторую информацию о том, как использовать обратный вызов и что userdata есть.
Как предполагает подпись, void* userdata
- это параметр, который можно использовать для отправки / получения данных для обратного вызова. Это чисто необязательно, поэтому, если вы не пользуетесь им, просто введите NULL
.
В приведенном ниже примере я буду использовать userdata для извлечения данных из обратного вызова. Вы могли заметить, что обратный вызов получает информацию state
от OpenCV. Я заинтересован в сохранении этого значения и сделать его доступным для main()
.
Для этого я определяю пользовательский тип данных и объявляю переменную этого типа в main()
. У пользовательского типа есть int
член для хранения state
, полученный нашим обратным вызовом, и мьютекс, который мы собираемся использовать для защиты пользовательского типа от одновременного чтения / записи двумя потоками (обратный вызов и main()
) .
#include <iostream>
#include <cv.h>
#include <highgui.h>
#include <pthread.h>
#include <string.h>
using namespace cv;
typedef struct custom_data
{
int state;
pthread_mutex_t mtx;
} custom_data_t;
void my_button_cb(int state, void* userdata)
{
std::cout << "@my_button_cb" << std::endl;
// convert userdata to the right type
custom_data_t* ptr = (custom_data_t*)userdata;
if (!ptr)
{
std::cout << "@my_button_cb userdata is empty" << std::endl;
return;
}
// lock mutex to protect data from being modified by the
// main() thread
pthread_mutex_lock(&ptr->mtx);
ptr->state = state;
// unlock mutex
pthread_mutex_unlock(&ptr->mtx);
}
int main()
{
// declare and initialize our userdata
custom_data_t my_data = { 0 };
createButton("dummy_button", my_button_cb, &my_data, CV_PUSH_BUTTON, 0);
// For testing purposes, go ahead and click the button to activate
// our callback.
// waiting for key press <enter> on the console to continue the execution
getchar();
// At this point the button exists, and our callback was called
// (if you clicked the button). In a real application, the button is
// probably going to be pressed again, and again, so we need to protect
// our data from being modified while we are accessing it.
pthread_mutex_lock(&my_data.mtx);
std::cout << "The state retrieved by the callback is: " << my_data.state << std::endl;
// unlock mutex
pthread_mutex_unlock(&my_data.mtx);
return 0;
}