2015-02-09 1 views
1

Чтобы не возиться с глобальными переменными и функциями, я хотел бы использовать функцию класса как функцию для дескриптора трека в OpenCV. Следующий код иллюстрирует идею:Кастинг C++ класс в другой для создания дескриптора OpenCV trackbar

void cam::set_Trackbarhandler(int i, void *func) 
{ 
    /* This function might be called whenever a trackbar position is changed */ 
} 

void cam::create_Trackbars(void) 
{ 
    /** 
    * create trackbars and insert them into main window. 
    * 3 parameters are: 
    * the address of the variable that is changing when the trackbar is moved, 
    * the maximum value the trackbar can move, 
    * and the function that is called whenever the trackbar is moved 
    */ 

    const string trck_name = "Exposure"; 
    char wnd_name[128]; 
    get_Mainwindowname(wnd_name, sizeof(wnd_name)); 


    createTrackbar(trck_name, //Name of the trackbar 
        wnd_name, //Name of the parent window 
        &setting, //value that's changed 
        (int)out_max, //maximum value 
        this->set_Trackbarhandler); //pointer to the function that's called 
} 

Я надеюсь, что это изложит его. Я получаю ошибку при компиляции читает

error: cannot convert 'cam::set_Trackbarhandler' from type 'void (cam::)(int, void*)' to type 'cv::TrackbarCallback {aka void (*)(int, void*)}'| 

Есть ли способ бросить void (cam::)(int, void*) в простой void (*)(int, void*) или я должен использовать глобальную функцию, то есть

void set_Trackbarhandler(int i, void *func) 

? Если я должен сделать это так, мое последнее средство, чтобы использовать указатель недействительным (см http://docs.opencv.org/modules/highgui/doc/user_interface.html) и отправить указатель на класс обратно, а

createTrackbar(trck_name, 
        wnd_name, 
        &setting, 
        (int)out_max, 
        set_Trackbarhandler, //now a global function 
        this); 

я думаю. В функции set_Trackbarhandler я хотел бы сделать слепок как

cam *ptr = static_cast<cam *>(func); 

Звучит немного сложнее, хотя.

+1

Вы не можете преобразовать указатель члена указатель на функцию. Если вы не хотите использовать глобальную функцию, объявите ее в пространстве имен. –

ответ

3

хорошо. вам нужно некоторые окольные, но это не так уж плохо ...

class cam 
{ 
public: 

    void myhandler(int value) 
    { 
     // real work here, can use 'this' 
    } 

    static void onTrack(int value, void* ptr) 
    { 
     cam* c = (cam*)(ptr); 
     c->myhandler(value); 
    } 
}; 

createTrackbar(trck_name, 
        wnd_name, 
        &setting, 
        (int)out_max, 
        cam::onTrack, //now a static member 
        this); 
+0

Это отлично работает. Хотите подчеркнуть важность шестого аргумента для createTrackbar(), так как статический обратный вызов получает дескриптор экземпляра. Я не пропустил это, и мне потребовалось пять минут, когда gdb задавался вопросом, почему это не работает. Но, увы: он делает, точно так же, как набирается. – Jameson

Смежные вопросы