wxThread::Run()’ is inaccessible within this context



  • Hallo,

    wie kann es sein, dass die Run() Methode auf dem Objekt, welches von wxThread abgeleitet wurde nicht ausführbar ist?

    #ifndef SECUREMONFRAME_H_
    #define SECUREMONFRAME_H_
    
    #include "RedisConnector.h"
    
    class SecureMonFrame: public wxFrame {
    public:
    	SecureMonFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
    	~SecureMonFrame();
        void DoStartThread();
        void DoPauseThread();
        void DoResumeThread();
        void OnThreadUpdate(wxThreadEvent&);
        void OnThreadCompletion(wxThreadEvent&);
        void OnClose(wxCloseEvent&);
    
    protected:
        RedisConnector *m_pThread;
        wxCriticalSection m_pThreadCS;    // protects the m_pThread pointer
    
    private:
    	void OnNewCon(wxCommandEvent& event);
    	void OnExit(wxCommandEvent& event);
    	void OnAbout(wxCommandEvent& event);
    
    	friend class RedisConnector;            // allow it to access our m_pThread
    
    	wxDECLARE_EVENT_TABLE();
    };
    
    #endif /* SECUREMONFRAME_H_ */
    
    #include <wx/wxprec.h>
    #ifndef WX_PRECOMP
    #include <wx/wx.h>
    #endif
    
    #include "RedisConnector.h"
    #include "SecureMonFrame.h"
    #include <wx/notebook.h>
    #include "icons/copy.xpm"
    #include "icons/paste.xpm"
    #include "icons/cut.xpm"
    
    enum {
    	ID_NEW_CON = 1,
    	ID_PANEL1 = 1,
    	ID_BUTTON1 = 1,
    	ID_BUTTON2 = 2,
    	ID_BUTTON3 = 3,
    };
    
    SecureMonFrame::SecureMonFrame(const wxString& title, const wxPoint& pos, const wxSize& size) : wxFrame(NULL, wxID_ANY, title, pos, size) {
    	/*
    	wxPanel *Panel1 = new wxPanel(this, ID_PANEL1);
    	Panel1->SetFont(wxFont(8, wxSWISS, wxNORMAL, wxNORMAL, false, wxT("Tahoma")));
    
    	wxButton *button = new wxButton(Panel1, ID_BUTTON1, "First");
    	wxButton *button2 = new wxButton(Panel1, ID_BUTTON2, "Don't click Me");
    	wxButton *button3 = new wxButton(Panel1, ID_BUTTON3, "Yay. Last one");
    
    	wxSizer *sizer = new wxBoxSizer(wxVERTICAL);
    	Panel1->SetSizer(sizer);
    
    	sizer->Add(button, 1, wxALIGN_RIGHT);
    	sizer->Add(button2, 1, wxALIGN_LEFT);
    	sizer->Add(button3, 1, wxALIGN_CENTER);
    
    	Panel1->SetSizer(sizer);
    	sizer->SetSizeHints(this);
    	*/
    
    	wxNotebook* notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxSize(300, 200));
    	//wxImageList* imageList = new wxImageList(8, 8, true, 3);
    	wxPanel* window1 = new wxPanel(notebook, wxID_ANY);
    	wxPanel* window2 = new wxPanel(notebook, wxID_ANY);
    	wxPanel* window3 = new wxPanel(notebook, wxID_ANY);
    	notebook->AddPage(window1, wxT("Tab A"), true);
    	notebook->AddPage(window2, wxT("Tab B"), true);
    	notebook->AddPage(window3, wxT("Tab C"), true);
    
    	wxMenu *menuProp = new wxMenu;
    	menuProp->Append(ID_NEW_CON, "&Neue Verbindung...\tCtrl-R", "Neue Verbindung zu einem Redis-Cluster/-Server konfigurieren");
    	menuProp->AppendSeparator();
    	menuProp->Append(wxID_EXIT);
    
    	wxMenu *menuHelp = new wxMenu;
    	menuHelp->Append(wxID_ABOUT, "&Über...\tCtrl-A", "Über Freistrom");
    
    	wxMenuBar *menuBar = new wxMenuBar;
    	menuBar->Append(menuProp, "&Einstellungen");
    	menuBar->Append(menuHelp, "&Hilfe");
    	SetMenuBar(menuBar);
    
    	CreateStatusBar();
    	SetStatusText("Freistrom Software GmbH (copyright 2018)");
    }
    
    SecureMonFrame::~SecureMonFrame(){}
    
    void SecureMonFrame::OnExit(wxCommandEvent& event) {
    	Close(true);
    }
    
    void SecureMonFrame::OnAbout(wxCommandEvent& event) {
    	wxMessageBox("Freistrom, das bin ich", "Freistrom Software GmbH", wxOK | wxICON_INFORMATION);
    }
    
    void SecureMonFrame::OnNewCon(wxCommandEvent& event) {}
    
    void SecureMonFrame::DoStartThread()
    {
        m_pThread = new RedisConnector(this);
        if ( m_pThread->Run() != wxTHREAD_NO_ERROR )
        {
            wxLogError("Can't create the thread!");
            delete m_pThread;
            m_pThread = NULL;
        }
        // after the call to wxThread::Run(), the m_pThread pointer is "unsafe":
        // at any moment the thread may cease to exist (because it completes its work).
        // To avoid dangling pointers OnThreadExit() will set m_pThread
        // to NULL when the thread dies.
    }
    
    void SecureMonFrame::OnThreadCompletion(wxThreadEvent&)
    {
        wxMessageOutputDebug().Printf("MYFRAME: MyThread exited!\n");
    }
    void SecureMonFrame::OnThreadUpdate(wxThreadEvent&)
    {
        wxMessageOutputDebug().Printf("MYFRAME: MyThread update...\n");
    }
    void SecureMonFrame::DoPauseThread()
    {
        // anytime we access the m_pThread pointer we must ensure that it won't
        // be modified in the meanwhile; since only a single thread may be
        // inside a given critical section at a given time, the following code
        // is safe:
        wxCriticalSectionLocker enter(m_pThreadCS);
        if (m_pThread)         // does the thread still exist?
        {
            // without a critical section, once reached this point it may happen
            // that the OS scheduler gives control to the MyThread::Entry() function,
            // which in turn may return (because it completes its work) making
            // invalid the m_pThread pointer
            if (m_pThread->Pause() != wxTHREAD_NO_ERROR )
                wxLogError("Can't pause the thread!");
        }
    }
    void SecureMonFrame::OnClose(wxCloseEvent&)
    {
        {
            wxCriticalSectionLocker enter(m_pThreadCS);
            if (m_pThread)         // does the thread still exist?
            {
                wxMessageOutputDebug().Printf("MYFRAME: deleting thread");
                if (m_pThread->Delete() != wxTHREAD_NO_ERROR )
                    wxLogError("Can't delete the thread!");
            }
        }       // exit from the critical section to give the thread
                // the possibility to enter its destructor
                // (which is guarded with m_pThreadCS critical section!)
        while (1)
        {
            { // was the ~MyThread() function executed?
                wxCriticalSectionLocker enter(m_pThreadCS);
                if (!m_pThread) break;
            }
            // wait for thread completion
            wxThread::This()->Sleep(1);
        }
        Destroy();
    }
    
    wxDECLARE_EVENT(wxEVT_COMMAND_MYTHREAD_COMPLETED, wxThreadEvent);
    wxDECLARE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent);
    
    wxBEGIN_EVENT_TABLE(SecureMonFrame, wxFrame)
    	EVT_MENU(ID_NEW_CON, SecureMonFrame::OnNewCon)
    	EVT_MENU(wxID_EXIT, SecureMonFrame::OnExit)
    	EVT_MENU(wxID_ABOUT, SecureMonFrame::OnAbout)
    	EVT_MENU(ID_NEW_CON,  SecureMonFrame::DoStartThread)
    	EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_MYTHREAD_UPDATE, SecureMonFrame::OnThreadUpdate)
    	EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_MYTHREAD_COMPLETED, SecureMonFrame::OnThreadCompletion)
    wxEND_EVENT_TABLE()
    
    #include <wx/wxprec.h>
    
    #ifndef WX_PRECOMP
    #include <wx/wx.h>
    #endif
    
    #ifndef REDISCONNECTOR_H_
    #define REDISCONNECTOR_H_
    
    #include <string>
    #include "xRedisClient.h"
    #include "xRedisPool.h"
    #include "xRedisCluster.h"
    #include "xLock.h"
    
    class SecureMonFrame;
    
    class RedisConnector : wxThread {
    	private:
    		RedisConnection con;
    		RedisNode node;
    		xRedisClient client;
    	public:
    		RedisConnector(SecureMonFrame *handler);
    		virtual ~RedisConnector();
    	protected:
    		virtual ExitCode Entry();
    		SecureMonFrame *m_pHandler;
    };
    
    #endif /* REDISCONNECTOR_H_ */
    
    #include "RedisConnector.h"
    #include "SecureMonFrame.h"
    #include <iostream>
    
    #define CACHE_TYPE_1 1
    #define CACHE_TYPE_2 2
    #define CACHE_TYPE_MAX 3
    
    // AP Hash Function
    unsigned int APHash(const char *str) {
        unsigned int hash = 0;
        int i;
        for (i=0; *str; i++) {
            if ((i&  1) == 0) {
                hash ^= ((hash << 7) ^ (*str++) ^ (hash >> 3));
            } else {
                hash ^= (~((hash << 11) ^ (*str++) ^ (hash >> 5)));
            }
        }
        return (hash&  0x7FFFFFFF);
    }
    
    RedisConnector::RedisConnector(SecureMonFrame *handler) : wxThread(wxTHREAD_DETACHED) {
    	m_pHandler = handler;
    	RedisNode RedisList[1] = {
    			{0, "127.0.0.1", 6379, "", 8, 5, 0}
    	};
    	xRedisClient xRedis;
    	xRedis.Init(CACHE_TYPE_MAX);
    	xRedis.ConnectRedisCache(RedisList, sizeof(RedisList) / sizeof(RedisNode), 1, CACHE_TYPE_1);
    	RedisDBIdx dbi(&xRedis);
    	const char* key = "key";
    	dbi.CreateDBIndex(key, APHash, CACHE_TYPE_1);
    	string value;
    	std::vector<string> channels = {"channel1"};
    	bool bRet = xRedis.get(dbi, key, value);
    	if (bRet) {
    			std::cout << value.c_str() << "\n";
    	    } else {
    	    	std::cout << dbi.GetErrInfo() << "\n";
    	}
    
    	xRedisContext ctx;
    	bRet = xRedis.subscribe(dbi, channels, ctx);
    	ReplyData vReply;
    	while (0 == xRedisClient::GetReply(&ctx, vReply)) {
    	            ReplyData::iterator iter = vReply.begin();
    	            for (; iter != vReply.end(); iter++) {
    	                printf("%d\t%s\r\n", (*iter).type, (*iter).str.c_str());
    	            }
    	}
    
    }
    
    RedisConnector::~RedisConnector()
    {
        wxCriticalSectionLocker enter(m_pHandler->m_pThreadCS);
        // the thread is being destroyed; make sure not to leave dangling pointers around
        m_pHandler->m_pThread = NULL;
    }
    
    wxThread::ExitCode RedisConnector::Entry()
    {
    	wxDEFINE_EVENT(wxEVT_COMMAND_MYTHREAD_COMPLETED, wxThreadEvent);
    	wxDEFINE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent);
    
        while (!TestDestroy())
        {
            // ... do a bit of work...
            wxQueueEvent(m_pHandler, new wxThreadEvent(wxEVT_COMMAND_MYTHREAD_UPDATE));
        }
        // signal the event handler that this thread is going to be destroyed
        // NOTE: here we assume that using the m_pHandler pointer is safe,
        //       (in this case this is assured by the MyFrame destructor)
        wxQueueEvent(m_pHandler, new wxThreadEvent(wxEVT_COMMAND_MYTHREAD_COMPLETED));
        return (wxThread::ExitCode)0;     // success
    }
    

    Seit meinem Studium habe ich fast kein C++ mehr geschrieben. Ich bitte daher um Nachsicht. Danke

    David



  • SOrry. Natürlich muss man auch die Fehlermeldung mit anhängen 😉

    Building file: ../src/SecureMonFrame.cpp
    Invoking: GCC C++ Compiler
    g++ -I/usr/lib/x86_64-linux-gnu/wx/include/gtk2-unicode-3.0 -I/usr/include/wx-3.0 -O0 -g3 -Wall -c -fmessage-length=0 -I/usr/lib/x86_64-linux-gnu/wx/include/gtk2-unicode-3.0 -I/usr/include/wx-3.0 -D_FILE_OFFSET_BITS=64 -DWXUSINGDLL -D__WXGTK__ -pthread -MMD -MP -MF"src/SecureMonFrame.d" -MT"src/SecureMonFrame.o" -o "src/SecureMonFrame.o" "../src/SecureMonFrame.cpp"
    ../src/SecureMonFrame.cpp: In member function ‘void SecureMonFrame::DoStartThread()’:
    ../src/SecureMonFrame.cpp:92:25: error: ‘wxThreadError wxThread::Run()’ is inaccessible within this context
         if ( m_pThread->Run() != wxTHREAD_NO_ERROR )
                             ^
    In file included from /usr/include/wx-3.0/wx/log.h:68:0,
                     from /usr/include/wx-3.0/wx/wx.h:23,
                     from ../src/SecureMonFrame.cpp:11:
    /usr/include/wx-3.0/wx/thread.h:534:19: note: declared here
         wxThreadError Run();
                       ^~~
    ../src/SecureMonFrame.cpp:92:25: error: ‘wxThread’ is not an accessible base of ‘RedisConnector’
         if ( m_pThread->Run() != wxTHREAD_NO_ERROR )
                             ^
    ../src/SecureMonFrame.cpp: In member function ‘void SecureMonFrame::DoPauseThread()’:
    ../src/SecureMonFrame.cpp:125:30: error: ‘wxThreadError wxThread::Pause()’ is inaccessible within this context
             if (m_pThread->Pause() != wxTHREAD_NO_ERROR )
                                  ^
    In file included from /usr/include/wx-3.0/wx/log.h:68:0,
                     from /usr/include/wx-3.0/wx/wx.h:23,
                     from ../src/SecureMonFrame.cpp:11:
    /usr/include/wx-3.0/wx/thread.h:567:19: note: declared here
         wxThreadError Pause();
                       ^~~~~
    ../src/SecureMonFrame.cpp:125:30: error: ‘wxThread’ is not an accessible base of ‘RedisConnector’
             if (m_pThread->Pause() != wxTHREAD_NO_ERROR )
                                  ^
    ../src/SecureMonFrame.cpp: In member function ‘void SecureMonFrame::OnClose(wxCloseEvent&)’:
    ../src/SecureMonFrame.cpp:136:35: error: ‘wxThreadError wxThread::Delete(void**, wxThreadWait)’ is inaccessible within this context
                 if (m_pThread->Delete() != wxTHREAD_NO_ERROR )
                                       ^
    In file included from /usr/include/wx-3.0/wx/log.h:68:0,
                     from /usr/include/wx-3.0/wx/wx.h:23,
                     from ../src/SecureMonFrame.cpp:11:
    /usr/include/wx-3.0/wx/thread.h:546:19: note: declared here
         wxThreadError Delete(ExitCode *rc = NULL,
                       ^~~~~~
    ../src/SecureMonFrame.cpp:136:35: error: ‘wxThread’ is not an accessible base of ‘RedisConnector’
                 if (m_pThread->Delete() != wxTHREAD_NO_ERROR )
                                       ^
    In file included from /usr/include/wx-3.0/wx/wx.h:24:0,
                     from ../src/SecureMonFrame.cpp:11:
    ../src/SecureMonFrame.cpp: At global scope:
    /usr/include/wx-3.0/wx/event.h:88:59: error: invalid static_cast from type ‘void (SecureMonFrame::*)()’ to type ‘wxCommandEventFunction {aka void (wxEvtHandler::*)(wxCommandEvent&)}’
     #define wxStaticCastEvent(type, val) static_cast<type>(val)
                                                               ^
    /usr/include/wx-3.0/wx/event.h:91:73: note: in definition of macro ‘wxDECLARE_EVENT_TABLE_ENTRY’
         wxEventTableEntry(type, winid, idLast, wxNewEventTableFunctor(type, fn), obj)
                                                                             ^~
    /usr/include/wx-3.0/wx/event.h:4129:5: note: in expansion of macro ‘wx__DECLARE_EVT2’
         wx__DECLARE_EVT2(evt, id, wxID_ANY, fn)
         ^~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:4320:31: note: in expansion of macro ‘wx__DECLARE_EVT1’
     #define EVT_MENU(winid, func) wx__DECLARE_EVT1(wxEVT_MENU, winid, wxCommandEventHandler(func))
                                   ^~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:148:49: note: in expansion of macro ‘wxStaticCastEvent’
         ( wxObjectEventFunction )( wxEventFunction )wxStaticCastEvent( functype, &func )
                                                     ^~~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:3906:5: note: in expansion of macro ‘wxEVENT_HANDLER_CAST’
         wxEVENT_HANDLER_CAST(wxCommandEventFunction, func)
         ^~~~~~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:4320:67: note: in expansion of macro ‘wxCommandEventHandler’
     #define EVT_MENU(winid, func) wx__DECLARE_EVT1(wxEVT_MENU, winid, wxCommandEventHandler(func))
                                                                       ^~~~~~~~~~~~~~~~~~~~~
    ../src/SecureMonFrame.cpp:162:2: note: in expansion of macro ‘EVT_MENU’
      EVT_MENU(ID_NEW_CON,  SecureMonFrame::DoStartThread)
      ^~~~~~~~
    /usr/include/wx-3.0/wx/event.h:88:59: error: invalid static_cast from type ‘void (SecureMonFrame::*)(wxThreadEvent&)’ to type ‘wxCommandEventFunction {aka void (wxEvtHandler::*)(wxCommandEvent&)}’
     #define wxStaticCastEvent(type, val) static_cast<type>(val)
                                                               ^
    /usr/include/wx-3.0/wx/event.h:91:73: note: in definition of macro ‘wxDECLARE_EVENT_TABLE_ENTRY’
         wxEventTableEntry(type, winid, idLast, wxNewEventTableFunctor(type, fn), obj)
                                                                             ^~
    /usr/include/wx-3.0/wx/event.h:4129:5: note: in expansion of macro ‘wx__DECLARE_EVT2’
         wx__DECLARE_EVT2(evt, id, wxID_ANY, fn)
         ^~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:4142:5: note: in expansion of macro ‘wx__DECLARE_EVT1’
         wx__DECLARE_EVT1(event, winid, wxCommandEventHandler(func))
         ^~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:148:49: note: in expansion of macro ‘wxStaticCastEvent’
         ( wxObjectEventFunction )( wxEventFunction )wxStaticCastEvent( functype, &func )
                                                     ^~~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:3906:5: note: in expansion of macro ‘wxEVENT_HANDLER_CAST’
         wxEVENT_HANDLER_CAST(wxCommandEventFunction, func)
         ^~~~~~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:4142:36: note: in expansion of macro ‘wxCommandEventHandler’
         wx__DECLARE_EVT1(event, winid, wxCommandEventHandler(func))
                                        ^~~~~~~~~~~~~~~~~~~~~
    ../src/SecureMonFrame.cpp:163:2: note: in expansion of macro ‘EVT_COMMAND’
      EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_MYTHREAD_UPDATE, SecureMonFrame::OnThreadUpdate)
      ^~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:88:59: error: invalid static_cast from type ‘void (SecureMonFrame::*)(wxThreadEvent&)’ to type ‘wxCommandEventFunction {aka void (wxEvtHandler::*)(wxCommandEvent&)}’
     #define wxStaticCastEvent(type, val) static_cast<type>(val)
                                                               ^
    /usr/include/wx-3.0/wx/event.h:91:73: note: in definition of macro ‘wxDECLARE_EVENT_TABLE_ENTRY’
         wxEventTableEntry(type, winid, idLast, wxNewEventTableFunctor(type, fn), obj)
                                                                             ^~
    /usr/include/wx-3.0/wx/event.h:4129:5: note: in expansion of macro ‘wx__DECLARE_EVT2’
         wx__DECLARE_EVT2(evt, id, wxID_ANY, fn)
         ^~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:4142:5: note: in expansion of macro ‘wx__DECLARE_EVT1’
         wx__DECLARE_EVT1(event, winid, wxCommandEventHandler(func))
         ^~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:148:49: note: in expansion of macro ‘wxStaticCastEvent’
         ( wxObjectEventFunction )( wxEventFunction )wxStaticCastEvent( functype, &func )
                                                     ^~~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:3906:5: note: in expansion of macro ‘wxEVENT_HANDLER_CAST’
         wxEVENT_HANDLER_CAST(wxCommandEventFunction, func)
         ^~~~~~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:4142:36: note: in expansion of macro ‘wxCommandEventHandler’
         wx__DECLARE_EVT1(event, winid, wxCommandEventHandler(func))
                                        ^~~~~~~~~~~~~~~~~~~~~
    ../src/SecureMonFrame.cpp:164:2: note: in expansion of macro ‘EVT_COMMAND’
      EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_MYTHREAD_COMPLETED, SecureMonFrame::OnThreadCompletion)
      ^~~~~~~~~~~
    src/subdir.mk:27: recipe for target 'src/SecureMonFrame.o' failed
    make: *** [src/SecureMonFrame.o] Error 1
    


  • Vielleicht meintest du

    class RedisConnector : public wxThread
    


  • Hi,

    danke das wars schon. Doch jetzt will er immer noch nicht richtig compilieren.

    make all 
    Building file: ../src/SecureMonFrame.cpp
    Invoking: GCC C++ Compiler
    g++ -I/usr/lib/x86_64-linux-gnu/wx/include/gtk2-unicode-3.0 -I/usr/include/wx-3.0 -O0 -g3 -Wall -c -fmessage-length=0 -I/usr/lib/x86_64-linux-gnu/wx/include/gtk2-unicode-3.0 -I/usr/include/wx-3.0 -D_FILE_OFFSET_BITS=64 -DWXUSINGDLL -D__WXGTK__ -pthread -MMD -MP -MF"src/SecureMonFrame.d" -MT"src/SecureMonFrame.o" -o "src/SecureMonFrame.o" "../src/SecureMonFrame.cpp"
    In file included from /usr/include/wx-3.0/wx/wx.h:24:0,
                     from ../src/SecureMonFrame.cpp:11:
    /usr/include/wx-3.0/wx/event.h:88:59: error: invalid static_cast from type ‘void (SecureMonFrame::*)()’ to type ‘wxCommandEventFunction {aka void (wxEvtHandler::*)(wxCommandEvent&)}’
     #define wxStaticCastEvent(type, val) static_cast<type>(val)
                                                               ^
    /usr/include/wx-3.0/wx/event.h:91:73: note: in definition of macro ‘wxDECLARE_EVENT_TABLE_ENTRY’
         wxEventTableEntry(type, winid, idLast, wxNewEventTableFunctor(type, fn), obj)
                                                                             ^~
    /usr/include/wx-3.0/wx/event.h:4129:5: note: in expansion of macro ‘wx__DECLARE_EVT2’
         wx__DECLARE_EVT2(evt, id, wxID_ANY, fn)
         ^~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:4320:31: note: in expansion of macro ‘wx__DECLARE_EVT1’
     #define EVT_MENU(winid, func) wx__DECLARE_EVT1(wxEVT_MENU, winid, wxCommandEventHandler(func))
                                   ^~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:148:49: note: in expansion of macro ‘wxStaticCastEvent’
         ( wxObjectEventFunction )( wxEventFunction )wxStaticCastEvent( functype, &func )
                                                     ^~~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:3906:5: note: in expansion of macro ‘wxEVENT_HANDLER_CAST’
         wxEVENT_HANDLER_CAST(wxCommandEventFunction, func)
         ^~~~~~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:4320:67: note: in expansion of macro ‘wxCommandEventHandler’
     #define EVT_MENU(winid, func) wx__DECLARE_EVT1(wxEVT_MENU, winid, wxCommandEventHandler(func))
                                                                       ^~~~~~~~~~~~~~~~~~~~~
    ../src/SecureMonFrame.cpp:37:2: note: in expansion of macro ‘EVT_MENU’
      EVT_MENU(ID_NEW_CON,  SecureMonFrame::DoStartThread)
      ^~~~~~~~
    /usr/include/wx-3.0/wx/event.h:88:59: error: invalid static_cast from type ‘void (SecureMonFrame::*)(wxThreadEvent&)’ to type ‘wxCommandEventFunction {aka void (wxEvtHandler::*)(wxCommandEvent&)}’
     #define wxStaticCastEvent(type, val) static_cast<type>(val)
                                                               ^
    /usr/include/wx-3.0/wx/event.h:91:73: note: in definition of macro ‘wxDECLARE_EVENT_TABLE_ENTRY’
         wxEventTableEntry(type, winid, idLast, wxNewEventTableFunctor(type, fn), obj)
                                                                             ^~
    /usr/include/wx-3.0/wx/event.h:4129:5: note: in expansion of macro ‘wx__DECLARE_EVT2’
         wx__DECLARE_EVT2(evt, id, wxID_ANY, fn)
         ^~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:4142:5: note: in expansion of macro ‘wx__DECLARE_EVT1’
         wx__DECLARE_EVT1(event, winid, wxCommandEventHandler(func))
         ^~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:148:49: note: in expansion of macro ‘wxStaticCastEvent’
         ( wxObjectEventFunction )( wxEventFunction )wxStaticCastEvent( functype, &func )
                                                     ^~~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:3906:5: note: in expansion of macro ‘wxEVENT_HANDLER_CAST’
         wxEVENT_HANDLER_CAST(wxCommandEventFunction, func)
         ^~~~~~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:4142:36: note: in expansion of macro ‘wxCommandEventHandler’
         wx__DECLARE_EVT1(event, winid, wxCommandEventHandler(func))
                                        ^~~~~~~~~~~~~~~~~~~~~
    ../src/SecureMonFrame.cpp:38:2: note: in expansion of macro ‘EVT_COMMAND’
      EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_MYTHREAD_UPDATE, SecureMonFrame::OnThreadUpdate)
      ^~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:88:59: error: invalid static_cast from type ‘void (SecureMonFrame::*)(wxThreadEvent&)’ to type ‘wxCommandEventFunction {aka void (wxEvtHandler::*)(wxCommandEvent&)}’
     #define wxStaticCastEvent(type, val) static_cast<type>(val)
                                                               ^
    /usr/include/wx-3.0/wx/event.h:91:73: note: in definition of macro ‘wxDECLARE_EVENT_TABLE_ENTRY’
         wxEventTableEntry(type, winid, idLast, wxNewEventTableFunctor(type, fn), obj)
                                                                             ^~
    /usr/include/wx-3.0/wx/event.h:4129:5: note: in expansion of macro ‘wx__DECLARE_EVT2’
         wx__DECLARE_EVT2(evt, id, wxID_ANY, fn)
         ^~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:4142:5: note: in expansion of macro ‘wx__DECLARE_EVT1’
         wx__DECLARE_EVT1(event, winid, wxCommandEventHandler(func))
         ^~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:148:49: note: in expansion of macro ‘wxStaticCastEvent’
         ( wxObjectEventFunction )( wxEventFunction )wxStaticCastEvent( functype, &func )
                                                     ^~~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:3906:5: note: in expansion of macro ‘wxEVENT_HANDLER_CAST’
         wxEVENT_HANDLER_CAST(wxCommandEventFunction, func)
         ^~~~~~~~~~~~~~~~~~~~
    /usr/include/wx-3.0/wx/event.h:4142:36: note: in expansion of macro ‘wxCommandEventHandler’
         wx__DECLARE_EVT1(event, winid, wxCommandEventHandler(func))
                                        ^~~~~~~~~~~~~~~~~~~~~
    ../src/SecureMonFrame.cpp:39:2: note: in expansion of macro ‘EVT_COMMAND’
      EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_MYTHREAD_COMPLETED, SecureMonFrame::OnThreadCompletion)
      ^~~~~~~~~~~
    src/subdir.mk:27: recipe for target 'src/SecureMonFrame.o' failed
    make: *** [src/SecureMonFrame.o] Error 1
    

    Mit der Fehlermeldung weiß ich nichts anzufangen



  • Wenn ich das jetzt richtig sehe, definierst du deine eigenen Events nicht: wxDEFINE_EVENT(http://docs.wxwidgets.org/3.1/group__group__funcmacro__events.html)



  • Ah ja. Bin ich eben grad auch drauf gestoßen. Habs wie folgt abgeändert. Aber der Fehler bleibt bestehen.

    /*
     * SecureMonFrame.cpp
     *
     *  Created on: Mar 15, 2018
     *      Author: david
     */
    
    // For compilers that support precompilation, includes "wx/wx.h".
    #include <wx/wxprec.h>
    #ifndef WX_PRECOMP
    #include <wx/wx.h>
    #endif
    
    #include "RedisConnector.h"
    #include "SecureMonFrame.h"
    #include <wx/notebook.h>
    #include "icons/copy.xpm"
    #include "icons/paste.xpm"
    #include "icons/cut.xpm"
    
    #define ID_NEW_CON 1
    #define ID_PANEL1 1
    #define ID_BUTTON1 1
    #define ID_BUTTON2 2
    #define ID_BUTTON3 3
    
    wxDEFINE_EVENT(wxEVT_COMMAND_REDISCONNECTOR_COMPLETED, wxThreadEvent);
    wxDEFINE_EVENT(wxEVT_COMMAND_REDISCONNECTOR_UPDATE, wxThreadEvent);
    
    wxBEGIN_EVENT_TABLE(SecureMonFrame, wxFrame)
    	EVT_MENU(ID_NEW_CON, SecureMonFrame::OnNewCon)
    	EVT_MENU(wxID_EXIT, SecureMonFrame::OnExit)
    	EVT_MENU(wxID_ABOUT, SecureMonFrame::OnAbout)
    	EVT_MENU(ID_NEW_CON,  SecureMonFrame::DoStartThread)
    	EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_REDISCONNECTOR_UPDATE, SecureMonFrame::OnThreadUpdate)
    	EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_REDISCONNECTOR_COMPLETED, SecureMonFrame::OnThreadCompletion)
    wxEND_EVENT_TABLE()
    
    SecureMonFrame::SecureMonFrame(const wxString& title, const wxPoint& pos, const wxSize& size) : wxFrame(NULL, wxID_ANY, title, pos, size) {
    	/*
    	wxPanel *Panel1 = new wxPanel(this, ID_PANEL1);
    	Panel1->SetFont(wxFont(8, wxSWISS, wxNORMAL, wxNORMAL, false, wxT("Tahoma")));
    
    	wxButton *button = new wxButton(Panel1, ID_BUTTON1, "First");
    	wxButton *button2 = new wxButton(Panel1, ID_BUTTON2, "Don't click Me");
    	wxButton *button3 = new wxButton(Panel1, ID_BUTTON3, "Yay. Last one");
    
    	wxSizer *sizer = new wxBoxSizer(wxVERTICAL);
    	Panel1->SetSizer(sizer);
    
    	sizer->Add(button, 1, wxALIGN_RIGHT);
    	sizer->Add(button2, 1, wxALIGN_LEFT);
    	sizer->Add(button3, 1, wxALIGN_CENTER);
    
    	Panel1->SetSizer(sizer);
    	sizer->SetSizeHints(this);
    	*/
    
    	wxNotebook* notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxSize(300, 200));
    	//wxImageList* imageList = new wxImageList(8, 8, true, 3);
    	wxPanel* window1 = new wxPanel(notebook, wxID_ANY);
    	wxPanel* window2 = new wxPanel(notebook, wxID_ANY);
    	wxPanel* window3 = new wxPanel(notebook, wxID_ANY);
    	notebook->AddPage(window1, wxT("Tab A"), true);
    	notebook->AddPage(window2, wxT("Tab B"), true);
    	notebook->AddPage(window3, wxT("Tab C"), true);
    
    	wxMenu *menuProp = new wxMenu;
    	menuProp->Append(ID_NEW_CON, "&Neue Verbindung...\tCtrl-R", "Neue Verbindung zu einem Redis-Cluster/-Server konfigurieren");
    	menuProp->AppendSeparator();
    	menuProp->Append(wxID_EXIT);
    
    	wxMenu *menuHelp = new wxMenu;
    	menuHelp->Append(wxID_ABOUT, "&Über...\tCtrl-A", "Über Freistrom");
    
    	wxMenuBar *menuBar = new wxMenuBar;
    	menuBar->Append(menuProp, "&Einstellungen");
    	menuBar->Append(menuHelp, "&Hilfe");
    	SetMenuBar(menuBar);
    
    	CreateStatusBar();
    	SetStatusText("Freistrom Software GmbH (copyright 2018)");
    }
    
    SecureMonFrame::~SecureMonFrame(){}
    
    void SecureMonFrame::OnExit(wxCommandEvent& event) {
    	Close(true);
    }
    
    void SecureMonFrame::OnAbout(wxCommandEvent& event) {
    	wxMessageBox("Freistrom, das bin ich", "Freistrom Software GmbH", wxOK | wxICON_INFORMATION);
    }
    
    void SecureMonFrame::OnNewCon(wxCommandEvent& event) {}
    
    void SecureMonFrame::DoStartThread()
    {
        m_pThread = new RedisConnector(this);
        if ( m_pThread->Run() != wxTHREAD_NO_ERROR )
        {
            wxLogError("Can't create the thread!");
            delete m_pThread;
            m_pThread = NULL;
        }
        // after the call to wxThread::Run(), the m_pThread pointer is "unsafe":
        // at any moment the thread may cease to exist (because it completes its work).
        // To avoid dangling pointers OnThreadExit() will set m_pThread
        // to NULL when the thread dies.
    }
    
    void SecureMonFrame::OnThreadCompletion(wxThreadEvent&)
    {
        wxMessageOutputDebug().Printf("MYFRAME: MyThread exited!\n");
    }
    void SecureMonFrame::OnThreadUpdate(wxThreadEvent&)
    {
        wxMessageOutputDebug().Printf("MYFRAME: MyThread update...\n");
    }
    void SecureMonFrame::DoPauseThread()
    {
        // anytime we access the m_pThread pointer we must ensure that it won't
        // be modified in the meanwhile; since only a single thread may be
        // inside a given critical section at a given time, the following code
        // is safe:
        wxCriticalSectionLocker enter(m_pThreadCS);
        if (m_pThread)         // does the thread still exist?
        {
            // without a critical section, once reached this point it may happen
            // that the OS scheduler gives control to the MyThread::Entry() function,
            // which in turn may return (because it completes its work) making
            // invalid the m_pThread pointer
            if (m_pThread->Pause() != wxTHREAD_NO_ERROR )
                wxLogError("Can't pause the thread!");
        }
    }
    void SecureMonFrame::OnClose(wxCloseEvent&)
    {
        {
            wxCriticalSectionLocker enter(m_pThreadCS);
            if (m_pThread)         // does the thread still exist?
            {
                wxMessageOutputDebug().Printf("MYFRAME: deleting thread");
                if (m_pThread->Delete() != wxTHREAD_NO_ERROR )
                    wxLogError("Can't delete the thread!");
            }
        }       // exit from the critical section to give the thread
                // the possibility to enter its destructor
                // (which is guarded with m_pThreadCS critical section!)
        while (1)
        {
            { // was the ~MyThread() function executed?
                wxCriticalSectionLocker enter(m_pThreadCS);
                if (!m_pThread) break;
            }
            // wait for thread completion
            wxThread::This()->Sleep(1);
        }
        Destroy();
    }
    


  • Also im Beispiel von wxThread Class Reference (welches du ja quasi kopiert hast) wird beides benutzt, also erst wxDECLARE_EVENT (im Header) und dann nach der EVENT_TABLE noch wxDEFINE_EVENT.

    Der Fehler meckert einen falschen Parameter bei der übergebenen Funktion an (wxCommandEvent) - wohl als Standard, welcher erst durch das wxDECLARE_EVENT als wxThreadEvent bekannt gemacht werden muß.

    Ansonsten müßtest du bei den Thread-Funktionen wxCommandEvent als Parameter angeben.



  • Hmmm, hab das jetzt echt alles durchprobiert und die DECLARE functions in SecureMonFrame.h definiert und dann vor jeder Verwendung in den cpp-Files RedisConnector.cpp und SecureMonFrame.cpp den DEFINE-Makro verwendet.

    Nebenbei: DoStartThread muss wxCommandEvent& übergeben bekommen. Das hat nämlich den gleichen Fehler verursacht ohne den Parameter. Da scheitn das Beispiel leicht Fehlerhaft zu sein oder veraltet.

    Aber die beiden REDISCONNECTOR Events bekomm ich einfach nicht zum laufen.
    Ich kapier das nicht. Es spielt auch keine Rolle ob ich DEFINE vor oder nach der EVENT_TABLE Definiton verwende. Hab ich auch schon probiert.

    #include "RedisConnector.h"
    
    wxDECLARE_EVENT(wxEVT_COMMAND_REDISCONNECTOR_COMPLETED, wxThreadEvent);
    wxDECLARE_EVENT(wxEVT_COMMAND_REDISCONNECTOR_UPDATE, wxThreadEvent);
    
    class SecureMonFrame: public wxFrame {
    ...
    
    wxDEFINE_EVENT(wxEVT_COMMAND_REDISCONNECTOR_COMPLETED, wxThreadEvent);
    wxDEFINE_EVENT(wxEVT_COMMAND_REDISCONNECTOR_UPDATE, wxThreadEvent);
    
    wxBEGIN_EVENT_TABLE(SecureMonFrame, wxFrame)
    	EVT_MENU(ID_NEW_CON, SecureMonFrame::OnNewCon)
    	EVT_MENU(wxID_EXIT, SecureMonFrame::OnExit)
    	EVT_MENU(wxID_ABOUT, SecureMonFrame::OnAbout)
    	EVT_CLOSE(SecureMonFrame::OnClose)
    	EVT_MENU(ID_START,  SecureMonFrame::DoStartThread)
    //	EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_REDISCONNECTOR_UPDATE, SecureMonFrame::OnThreadUpdate)
        EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_REDISCONNECTOR_COMPLETED, SecureMonFrame::OnThreadCompletion)
    wxEND_EVENT_TABLE()
    
    SecureMonFrame::SecureMonFrame(const wxString& title, const wxPoint& pos, const wxSize& size) : wxFrame(NULL, wxID_ANY, title, pos, size) {
    	...
    
    wxDEFINE_EVENT(wxEVT_COMMAND_REDISCONNECTOR_COMPLETED, wxThreadEvent);
    wxDEFINE_EVENT(wxEVT_COMMAND_REDISCONNECTOR_UPDATE, wxThreadEvent);
    wxThread::ExitCode RedisConnector::Entry()
    {
        while (!TestDestroy())
        {
            // ... do a bit of work...
            wxQueueEvent(m_pHandler, new wxThreadEvent(wxEVT_COMMAND_REDISCONNECTOR_UPDATE));
        }
        // signal the event handler that this thread is going to be destroyed
        // NOTE: here we assume that using the m_pHandler pointer is safe,
        //       (in this case this is assured by the MyFrame destructor)
        wxQueueEvent(m_pHandler, new wxThreadEvent(wxEVT_COMMAND_REDISCONNECTOR_COMPLETED));
        return (wxThread::ExitCode)0;     // success
    }
    


  • Ich habe bei mir jetzt nochmal nachgeschaut.

    Ich habe in einem Header wxDECLARE_EVENT und im dazugehörigen Source File wxDEFINE_EVENT.

    Ansonsten benutze ich persönlich Bind() anstelle von einem event table.

    Was heißt denn genau "nicht zum laufen gebracht"?
    Kompiliert nicht, event wird nicht erzeugt, oder event wird nicht richtig verarbeitet?



  • Hallo,

    er kompiliert nicht durch und bricht mit dem oben beschriebenen Fehler ab

    /usr/include/wx-3.0/wx/event.h:88:59: error: invalid static_cast from type ‘void (SecureMonFrame::*)(wxThreadEvent&)’ to type ‘wxCommandEventFunction {aka void (wxEvtHandler::*)(wxCommandEvent&)}’
    #define wxStaticCastEvent(type, val) static_cast<type>(val)
    


  • Was mir auf die Schnelle noch auffällt: Du hast 3x die Id 1 vergeben.
    Ich bin mir grade auch nicht sicher, welche IDs wxWidgets intern verwendet. Bei Custom IDs nehme ich immer > 10000. Aber ich finde den Teil in der Doku grade nicht.

    Wenn du die beiden Zeilen im Event Table mit den EVT_COMMAND Events auskommentierst, kompiliert der Code?

    Edit: Im Sample wird das auch anders gemacht. Gibt es einen Grund, warum du nicht wxEVT_THREAD verwendest, mit entsprechenden IDs?

    Sonst evt. sowas im Header:

    #define EVT_COMMAND_REDISCONNECTOR_UPDATE(id, func) wx__DECLARE_EVT1(wxEVT_COMMAND_REDISCONNECTOR_UPDATE, id, &func);
    

    und dann im event table:

    wxBEGIN_EVENT_TABLE()
         EVT_COMMAND_REDISCONNECTOR_UPDATE(wxID_ANY, SecureMonFrame::OnThreadUpdate) 
     wxEND_EVENT_TABLE()
    

  • Mod

    Evtl. hilft das wxWidgets tutorial, dort hatte ich einen eigenen Event erstellt:
    https://www.c-plusplus.net/forum/175682


Log in to reply