a non static member reference must be relative to a specific object

0

I have been building a simple application which requires a separate thread to run some background code in a while loop. I have a text box which I want to send messages to from the code running in the separate thread however I am unable to.

A non static member reference must be relative to a specific object. From my understanding to run an additional thread it seems that I have to make the function static. However when I try and write a message to m_Console I see the error:

A non static member reference must be relative to a specific object.

I tried initialising the object but it doesn't do anything.

CMFCApplication1Dlg  obj;
obj.m_Console = "Test"
  • The code that uses a separate thread is: static UINT checkSomething(LPVOID pParam);

  • The text box variable is: CString m_Console;

void CMFCApplication1Dlg::OnBnClickedBtnAdd(){
m_Console = "Parser is now running..";
AfxBeginThread(checkSomething,"");

I have tried the suggestion:

UINT CMFCApplication1Dlg::checkSomething(LPVOID pParam){
    CMFCApplication1Dlg* pObject = (CMFCApplication1Dlg*)pParam;
    pObject->m_Console = "I am in thread";

But it throws an access violation error on: pObject->m_Console = "I am in thread";

Exception thrown at 0x0FE90DBD (mfc140ud.dll) in MFCApplication1.exe: 0xC0000005: Access violation reading location 0xFFFFFFFC.

Here is the code:

MFCApplication1Dlg.cpp

void CMFCApplication1Dlg::OnBnClickedBtnAdd(){      


m_Console = "Something Parser is now running..";
AfxBeginThread(checkSomething,"");

CWnd* okbtn = GetDlgItem(IDC_BTN_ADD);
if (okbtn) {
    okbtn->EnableWindow(FALSE);
}

// without UpdateData() status area will _NOT_ be updated.
UpdateData(FALSE);}


INT CMFCApplication1Dlg::checkSomething(LPVOID pParam){

CMFCApplication1Dlg* pObject = (CMFCApplication1Dlg*)pParam;

pObject->m_Console = "I am in thread";

MFCApplication1Dlg.h

public:
afx_msg void OnBnClickedBtnAdd();
static int messenger();
static UINT checkSomething(LPVOID pParam);
CString m_Console;

Textbox: IDC_Console

  • Category: value
  • Access: public
  • Control type: LText
  • Name: m_Console
  • Variable type: CString

From reading everyone's comments, it seems as if this is something that I am not supposed to do in C++, question is then, what if I had a background task running a loop in in a separate thread which needed to update the status box on the UI? To me that seems a logical thing someone might wish to do but if I'm not supposed to do that then how would that be done? I am running the task in a separate thread because it uses a while loop and if I don't use a separate thread it just freezes the whole application.

c++
mfc
asked on Stack Overflow Dec 28, 2019 by Mr Tea • edited Dec 28, 2019 by Mr Tea

2 Answers

1

You can deliver the object of CMFCApplication1Dlg as parameter for the Thread function.

e.g

UINT MyThreadProc( LPVOID pParam )
{
    CMFCApplication1Dlg * pObject = (CMFCApplication1Dlg *)pParam;

    pObject->m_Console = "I am in thread";
}

// .... .... ... 

AfxBeginThread(MyThreadProc, this);

I hope this answer will work for you.

answered on Stack Overflow Dec 28, 2019 by ysk silver • edited Dec 28, 2019 by Ted Lyngmo
0

Changed

AfxBeginThread(checkSomething,""); to

AfxBeginThread(checkSomething,this);

as suggested by ysk silver, thanks!

I needed to add a Timer Function which I followed this article: https://www.tutorialspoint.com/mfc/mfc_multithreading.htm

Once I did this, the UI box updates.

int currValue;int maxValue;BOOL stopNow;string output;


BEGIN_MESSAGE_MAP(CMFCApplication1Dlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_ERASEBKGND()
ON_WM_CTLCOLOR()
ON_WM_TIMER()  //TIMER
ON_BN_CLICKED(IDC_BTN_ADD, &CMFCApplication1Dlg::OnBnClickedBtnAdd)

END_MESSAGE_MAP()

void CMFCApplication1Dlg::OnTimer(UINT_PTR nIDEvent) {

CDialogEx::OnTimer(nIDEvent);
UpdateData(FALSE);}

void CMFCApplication1Dlg::OnBnClickedBtnAdd(){      
SetTimer(1234, 333, 0); // 3 times per second
m_Console = "Parser is now running..";
AfxBeginThread(checkSomething,this);

I then can change the text in the checkSomething method:

CMFCApplication1Dlg* pObject = (CMFCApplication1Dlg*)pParam;
output = "I am in thread";
pObject->messenger(output);
//OR
  pObject->m_Console = "I am in thread";

And the textbox updates!

answered on Stack Overflow Dec 28, 2019 by Mr Tea • edited Dec 28, 2019 by Mr Tea

User contributions licensed under CC BY-SA 3.0