2013-08-08 2 views
2

У меня есть небольшая проблема с использованием библиотеки, которая получает изображения с CMOS-камеры. Библиотека позволяет использовать функцию потока, и у меня есть три точки доступа для установки (три делегата), когда я получаю изображение, когда изображение удаляется и когда появляется ошибка.C делегат на C++

typedef void(* StreamCallbackPtr)(IMAGE *image); 
typedef void(* StreamErrorCallbackPtr)(); 
typedef void(* StreamFrameDroppedCallbackPtr)(); 

int Stream_Start(DEVICE device, IMAGEFORMAT format, StreamCallbackPtr stream_callback, StreamFrameDroppedCallbackPtr f_dropped_callback, StreamErrorCallbackPtr error_callback); 

Я ввожу StreamCallbackPtr как только изображение будет готово на камеру, но имейте в виду, что у меня нет никаких способов изменения кода библиотеки.

И вот вопрос: как подключить собственный делегат на C++? Допустим, я использую эту функцию потока внутри класса, я знаю, что у меня есть как минимум два варианта; обертка и глобальные переменные. Первый кажется скомпрометированным, поскольку я не могу передать ничего, кроме IMAGE, и я хочу избежать использования глобальных переменных (в этом случае это были бы статические члены).

Любые идеи?

+1

Это должно помочь вам: http://stackoverflow.com/questions/14395192/why-does-c11-not-support-declaring-extern-c-on-a-static-member-function –

ответ

3

Вы можете использовать статическую функцию-член как StreamCallbackPtr, которая затем может получить доступ к частной статической ссылке или списку ссылок на делегатов C++, которые хотят получить сообщение.

Таким образом, вы скрыли большую часть деталей как конфиденциальных для класса.

Код ниже - псевдо-C++ (я не проверял его правильно), но он должен дать вам представление о том, что я предлагаю.

class Delegate 
{ 
protected: 
    void Callback(IMAGE *image) = 0; 
    void Error() = 0; 
    void FrameDropped() = 0; 

public: 
    static void SetDelegate(Delegate* d) { delegateInstance = d; } 

    static void StaticCallback(IMAGE *image) 
    { 
     // Invoke the delegate instance 
     if (delegateInstance != nullptr) delegateInstance->Callback(); 
    } 
    // Same for the others... 

private: 
    static Delegate* delegateInstance = nullptr; 
}; 

class MyClass : public Delegate 
{ 
protected: 
    void Callback(IMAGE *image) 
    { 
     // Now the callback is in a delegate instance 
    } 
}; 

int main(void) 
{ 
    MyClass mc; 
    Delegate::SetDelegate(&mc); 

    StreamCallbackPtr scp = &Delegate::StaticCallback; 
    // Register the other static callbacks... 

    return 0; 
} 
+0

I Думаю, я понял, но у вас есть пример? И тогда делегаты C++ должны быть статичными ... – Athanase

+0

Спасибо за код, я попробовал это уже, но еще раз спасибо. Но есть ли способ не иметь статического делегата? – Athanase

+0

Вы просто не пересылаете вызов экземпляру. Я снова прочитал ваш пост, был ли мой пример оберткой? Если да, то почему это скомпрометировано? – DrYap

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