Search code examples
c++ccallbackpthreadswxwidgets

How to make a wxWidget method that could be used as a callback in C library?


I have a shared C library, that read data from COM port in a separate thread. And a C++ wxWidget application, that wait a data from lib and render it in UI. I need to make a callback function, that lib will call, when collect a correct packet of data. I've made a static var in wxWidget frame class, which contain a pointer to the object of this class and a static method, pointer to which I give to a library as a callback. Thats callback work, but in this cause I can't modify the UI. The program crashed with SIGABRT signal. As I see, it's a bad way to modify an wxWidgets UI from a non-main thread. But I dont know how to do it another. Can you help me? Thank you.


Solution

  • Yes, you can only use wxWidgets GUI functions from a single (commonly called "main", but it doesn't have to be the actual main thread of the application, just the one from which wxWidgets was initialized) thread. The only thing you can do from another thread safely is to post an event to the GUI thread asking it to perform something on this thread behalf, see wxQueueEvent().

    Since wxWidgets 3.0 there is a convenient wrapper, using the same underlying mechanism, called CallAfter(). Especially if you use C++11, it's very simple to use as you can just pass it the code to be executed in the main thread directly, e.g.

    void MyThreadCallback(void* data)
    {
        wxTheApp->CallAfter([=]() {
            wxMessageBox("This is safe because we're in the main thread now");
            // Do whatever you need to do with "data"
        });
    }