Search code examples
c++wxwidgets

illegal reference to non-static member or unresolved external symbol


I'm trying to learn c++ with wxWidgets. Till now all my programs were written in plain C (no needs for objects), vba, bash - as you see I'm not programer.

Even if this example is in frame of wxWidgets it's general c++ problem (actually it's mine problem with c++ ;-)

The main windows has a menu-bar with sub-menu Settings/Communication. I have defined a class that for a main frame in startup.h:

class startUp: public wxFrame
{    
    DECLARE_CLASS( startUp)
    DECLARE_EVENT_TABLE()
public:
    startUp();
    startUp( wxWindow* parent, wxWindowID id = SYMBOL_....
    ~startUp();
    void OnMENUCommunicationClick( wxCommandEvent& event );
    ....
    void SetDevName(const wxString& devname);
protected:
    static wxString devName;
};

and startup.cpp:

....
void startUp::SetDevName(const wxString& devname) 
{
    devName=_T(devname);
}

The OnMENUCommunicationClick calls a dialog that should return the name of the device selected in wxChoice (btw, feeding of the wxChoice works). This dialog defined in another class:

#include "startup.h"
class Communication: public wxFrame
{  
....
void Communication::CreateControls();
protected:
    wxArrayString portChoiceStrings;

communication.cpp:

...
void Communication::CreateControls()
    std::vector<std::string> ports;
    int count = ScanSerialPorts( ports, true );
    for( int i = 0; i < count; i++ ) {
       portChoiceStrings.Add( wxString( ports[ i ].c_str(), wxConvUTF8 ) );
    }
    portChoice = new wxChoice( itemPanel2, ID_ComportSet, wxPoint(108, 25), wxSize(55, -1), portChoiceStrings, 0 );
    portChoice->SetSelection(0);
....
}

void Communication::OnOKClick( wxCommandEvent& event )
{
    startUp::SetDevName(_T(portChoiceStrings[portChoice->GetSelection()]));
    //startUp::SetDevName(wxT(""));
    Destroy();
}

Now to my problem I hoped that OnOKClick would return to startUp selected device. What I've got is: c2352 illegal call of non-static member function. As the member of startUp is not initialized my option was to change in startup.h both function and variable to static.

static void SetDevName(const wxString& devname);
static wxString devName;

The things improved - all files compile but linker says unresolved external symbol "protected: static class wxString startUp::devName". Moving devName from protected to public doesn't change a thing.

Can somebody explain me what is "the proper" way of passing values between classes? I wouldn't like to use global variables to solve it. Apparently these are evil.


Solution

  • I've found solution. I've removed word static from definitions.

    In class startup after initialize of dialog window I've add a call to function setLink:

    void startUp::OnMENUCommunicationClick( wxCommandEvent& event )
        {
        Communication* window = new Communication(this,ID_COMMUNICATION, _("Communication Settings"));
        window->setLink(this);
        int returnValue = window->Show();
        }
    

    Than in class Communication I've added a link function setLink that stores pointer of main window:

    void Communication::setLink(startUp* papi)
        {
        this->m_link = papi;
        }
    

    which I could use in OnSetClick :

    void Communication::OnSetClick( wxCommandEvent& event )
        {
        m_link->SetDevName(_T(portChoiceStrings[portChoice->GetSelection()]));
        Destroy();
        }
    

    The m_link variable was defined in communication.h as a member of startUp class:

    startUp* m_relative;   
    

    Everything works (i.e. program compiles and links without errors and the devName variable from startUp-Frame is set to value read from Communication menu.