GetDlgItemText and Multithreading - c++

So I have been trying to implement the concept of multithreading to an MFC application I am making. I used the method suggested here. It works fine but I am having an issue with using data given by the user while the thread is working.
I'll explain.
I am making a simple GUI to send and receive data over a serial port. So the data in IDC_SEND is user-input, and is then sent through the serial port. I am using the WINAPI definition of GetDlgItemText, but since the controlling function for AfxBeginThread is defined as a static function I cannot do this. So I tried ::GetDlgItemText, but that calls the CWnd definition which takes one or three or four(?) arguments.
So ::GetDlgItemText(IDC_SEND, CString text) doesn't work. This problem continues for SetDlgItemText too.
I have tried getting the data outside my controlling function, but since it is defined to return a UINT type, I cannot get the received data out.
The relevant code
void CCommTest2Dlg::OnButton()
{
THREADSTRUCT *_param = new THREADSTRUCT;
_param->_this = this;
AfxBeginThread (StartThread, _param);
}
UINT CCommTest2Dlg::StartThread(LPVOID param)
{
THREADSTRUCT* ts = (THREADSTRUCT*)param;
AfxMessageBox ("Thread is started!");
//Opened Serial Port
//Writing data from Editbox
CString text;
::GetDlgItemText(IDC_SEND,text);//********ERROR HERE!!
serial.Write(text);
//At Receiver port data is wriiten into CString a.
CString a;
::SetDlgItemText( IDC_RECV, a);//Apparently this calls the SetDlgItemText from the CWnd class, and not the Windows API that takes more than one argument.
AfxMessageBox ((LPCTSTR)a);//This works, but I need the data in the EditBox.
//Closing Ports
delete ts; //Edit 1
return 1;}
A few definitions:
static UINT StartThread (LPVOID param);
//structure for passing to the controlling function
typedef struct THREADSTRUCT
{
CCommTest2Dlg* _this;
} THREADSTRUCT;
UINT StartThread(void);
Any thoughts?
PS: Also Edit 1 at the end was added by me as I read that this implementation could result in memory leaks. Does it look like the addition might have fixed that?

Related

How to implement OOBE complete notification in c++?

I want to do a win32 implementation of RegisterWaitUntilOOBECompleted API for my app.
The goal is to detect OOBE complete and perform specific operations.
However, I don't quite understand how to implement it in c++ code.
I spent the past 6 hours looking for sample implementation but to no luck.
Can anyone explain how to do it?
Registers a callback to be called once OOBE (Windows Welcome) has been
completed.
Syntax C++
BOOL RegisterWaitUntilOOBECompleted( OOBE_COMPLETED_CALLBACK
OOBECompletedCallback, PVOID CallbackContext,
PVOID *WaitHandle );
Parameters
OOBECompletedCallback
Pointer to an application-defined callback function that will be
called upon completion of OOBE. For more information, see
OOBE_COMPLETED_CALLBACK.
CallbackContext
Pointer to the callback context. This value will be passed to the
function specified by OOBECompletedCallback. This value can be nulll.
WaitHandle
Pointer to a variable that will receive the handle to the wait
callback registration.
For anyone in the future who might be looking for sample implementation of this API, here's how I did it. This sample code is not intended to compile though.
Header file
#include "Oobenotification.h"
class MainClass
{
// put constructor here
// destructor
~MainClass();
// OOBE notification
OOBE_COMPLETED_CALLBACK OOBECompletedCallback;
PVOID m_OOBEHandle = NULL;
// receive notification one OOBE complete
void OOBERegisterNotification();
static void CALLBACK NotifyOOBEComplete(PVOID CallbackContext);
public:
Init();
};
CPP file
#include "header.h"
void MainClass::~MainClass()
{
if (m_OOBEHandle != NULL)
UnregisterWaitUntilOOBECompleted(m_OOBEHandle);
}
void MainClass::Init()
{
// register to receive oobe complete notification
OOBERegisterNotification();
}
void MainClass::OOBERegisterNotification()
{
OOBECompletedCallback = &NotifyOOBEComplete;
BOOL bRes = ::RegisterWaitUntilOOBECompleted(OOBECompletedCallback, NULL, &m_OOBEHandle);
if (!bRes)
{
// handle failed registration here
}
}
void CALLBACK MainClass::NotifyOOBEComplete(PVOID Context)
{// async
UNREFERENCED_PARAMETER(Context);
// what you want to do after OOBE
}

Connecting callback to thread

I am calling a library function which also need a callback function as its only argument. It is time consuming function and the callback is called frequently to pass messages to the client (my application) to display. The problem is I want to copy the message and pass it onto the main thread for display but because it is callback function, I see no other way but to use globals to do that and that's what I am trying to avoid/make better.
The callback is static member function of my CTestDlg which alrady has m_hWnd member where I want to post the messages. However for the sake of callback I have yet defined another static g_hWnd member so my callback can access it and post message to it. This part doesn't look very nice to me but my callback routine is collecting messages wonderfully.
My callback function is the following
void CTestDlg::OnNotify (int code, const char * msg)
{
char * message = NULL; // to copy the message
message = new char[ strlen( msg) + 1 ]();
strcpy_s( message, strlen(msg) +1, msg );
PostMessageA( g_hWnd, ID_NOTIFY_MSG, code, (LPARAM) message );
}
I am running the library call in a separate thread and because it is callback to that function, it also runs in the same thread. Is there a better way to change hand in this callback function and pass the message to main thread or a particularly window to display?
If your callback is a static method, it has no access to instance data, so you must store your state data (the main window handle, in your case) in a static or global variable.
You can move the handle from a global variable to a static CTestDlg::s_hWnd variable.

Pointers to member functions within the same class (C++)?

I am writing a program to control a auto home brewing system on an Arduino Mega micro controller (written in C/C++). In short, what the program is doing is there is a C# application which periodically sends messages through USB to the micro controller. There is then a messaging interface which I wrote which reads the message, and forwards it to whichever component the message is for. Each message is 16 bytes long, the first 4 is a transaction code, and the last 12 is for data. Now, I read in the message and forward to it to my StateController class. It comes in from the InboundMessage function. What I am trying to do is I have a struct (defined in StateController.h) which contains the transaction code and pointer to a member function within StateController. I defined a QueueList (just a simple linked list library), and pushed a bunch of these structs into it. What I would like to do is then when a message comes into the inboundMessage function, i would like to loop through the linked list until I find a transaction code which matches, and then call the member function which is for that message, passing it the data in the message.
I think I have everything initialized correctly, but here is the problem. When I try and compile I get an error saying "func does not exist in this scope". I have looked all over for a solution to this, but can not find one. My codes is below
StateController.cpp
StateController::StateController(){
currentState = Idle;
prevState = Idle;
lastRunState = Idle;
txnTable.push((txnRow){MSG_BURN, &StateController::BURNprocessor});
txnTable.push((txnRow){MSG_MANE, &StateController::MANEprocessor});
txnTable.push((txnRow){MSG_MAND, &StateController::MANDprocessor});
txnTable.push((txnRow){MSG_PUMP, &StateController::PUMPprocessor});
txnTable.push((txnRow){MSG_STAT, &StateController::STATprocessor});
txnTable.push((txnRow){MSG_SYNC, &StateController::SYNCprocessor});
txnTable.push((txnRow){MSG_VALV, &StateController::VALVprocessor});
}
void StateController::inboundMessage(GenericMessage msg){
// Read transaction code and do what needs to be done for it
for (int x = 0; x < txnTable.count(); x++)
{
if (compareCharArr(msg.code, txnTable[x].code, TXN_CODE_LEN) == true)
{
(txnTable[x].*func)(msg.data);
break;
}
}
}
StateController.h
class StateController{
// Public functions
public:
// Constructor
StateController();
// State Controller message handeler
void inboundMessage(GenericMessage msg);
// Main state machine
void doWork();
// Private Members
private:
// Hardware interface
HardwareInterface hardwareIntf;
// Current state holder
StateControllerStates currentState;
// Preveous State
StateControllerStates prevState;
// Last run state
StateControllerStates lastRunState;
// BURN Message Processor
void BURNprocessor(char data[]);
// MANE Message Processor
void MANEprocessor(char data[]);
// MAND Message Processor
void MANDprocessor(char data[]);
// PUMP Message Processor
void PUMPprocessor(char data[]);
//STAT Message Processor
void STATprocessor(char data[]);
// SYNC Message Processor
void SYNCprocessor(char data[]);
// VALV Message Processor
void VALVprocessor(char data[]);
void primePumps();
// Check the value of two sensors given the window
int checkSensorWindow(int newSensor, int prevSensor, int window);
struct txnRow{
char code[TXN_CODE_LEN + 1];
void (StateController::*func)(char[]);
};
QueueList<txnRow> txnTable;
};
Any idea what is wrong?
func is just a normal member of txnRow so you access it with ., not .*, e.g. txnTable[x].func.
To call this member function on, say, this, you would do something like:
(this->*(txnTable[x].func))(msg.data);

Cannot lock Qt mutex (QReadWriteLock) Access violation writing

Some background for this question is my previous question:
non-member function pointer as a callback in API to member function (it may well be irrelevant).
The callback launches a thread that writes some data. There is another thread that reads the same data, and that results in some crashes.
I just took a crash course in multi-threading (thanks SO), and here is my attempt to guarantee that the data isn't accessed by the writer and the reader at the same time. I'm using some mutex mechanism from Qt (QReadWriteLock).
#include <QSharedPointer>
#include <QReadWriteLock>
Class MyClass
{
public:
MyClass();
bool open();
float getData();
void streamCB(void* userdata);
protected:
float private_data_;
QSharedPointer<QReadWriteLock> lock_;
};
// callback wrapper from non-member C API to member function void
__stdcall streamCBWrapper(void* userdata)
{
static_cast<MyClass*>(userdata)->streamCB(userdata);
}
// constructor
MyClass::MyClass()
{
lock_ = QSharedPointer<QReadWriteLock>(new QReadWriteLock());
lock_->lockForWrite();
private_data_ = getData();
lock_->unlock();
}
// member callback
void MyClass:streamCB(void* userdata)
{
float a = getData();
lock_->lockForWrite(); //*** fails here
private_data_ = a;
lock_->unlock();
}
I have a segmentation fault while running the program. The VS debugger says Access violation writing location 0x00fedbed. on the line that I marked //*** fails here.
The lock worked in the constructor, but not in the callback.
Any idea what goes wrong? What should I look at? (and how can I refine my question)
Thanks!
Other relevant thread
Cannot access private member declared in class 'QReadWriteLock'Error 1 error C2248: 'QReadWriteLock::QReadWriteLock' (I used the QSharedPointer suggestion)
Edit 1:
The callback is set up
bool MyClass::open()
{
// stuffs
int mid = 0;
set_stream_callback(&streamCBWrapper, &mid);
// more stuffs
return true;
}
Edit 2:
Thank you for all the suggestions.
So my mistake(s) may not be due at all to the mutex, but to my lack of understanding of the API? I'm quite confused.. Here is the API doc for the set_stream_callback.
typedef void (__stdcall *STREAM_CALLBACK)(void *userdata);
/*! #brief Register a callback to be invoked when all subscribed fields have been updated
*
* #param streamCB pointer to callback function
* #param userdata pointer to private data to be passed back as argument to callback
* #return 0 if successful, error code otherwise
*/
__declspec(dllimport) int __stdcall set_stream_callback(
STREAM_CALLBACK streamCB, void *userdata);
Good example why sufficient code example is required.
If I interpret your callback syntax correctly,
set_stream_callback(&streamCBWrapper, &mid);
sets streamCBWrapper as callback function, while &mid is the pointer to userdata.
In the callback, you are actually now casting a pointer to int to MyClass, then try to access a member variable of a non-existant object.
Make sure to pass an instance of MyClass to your callback. I assume this would be this in your case.
Sounds fundamentally like a threading issue to me. Since you're using the Qt mutexing anyway, you might consider using Qt's threading mechanisms and sending signals and slots between the threads. They're pretty well documented and easy to use as long as you follow the suggestions here and here.

ESP error when sending window messages between threads

I have an Observer class and a Subscriber class.
For testing purposes, the observer creates a thread that generates fake messages and calls CServerCommandObserver::NotifySubscribers(), which looks like this:
void CServerCommandObserver::NotifySubscribers(const Command cmd, void const * const pData)
{
// Executed in worker thread //
for (Subscribers::const_iterator it = m_subscribers.begin(); it != m_subscribers.end(); ++it)
{
const CServerCommandSubscriber * pSubscriber = *it;
const HWND hWnd = pSubscriber->GetWindowHandle();
if (!IsWindow(hWnd)) { ASSERT(FALSE); continue; }
SendMessage(hWnd, WM_SERVERCOMMAND, cmd, reinterpret_cast<LPARAM>(pData));
}
}
The subscriber is a CDialog derived class, that also inherits from CServerCommandSubscriber.
In the derived class, I added a message map entry, that routes server commands to the subscriber class handler.
// Derived dialog class .cpp
ON_REGISTERED_MESSAGE(CServerCommandObserver::WM_SERVERCOMMAND, HandleServerCommand)
// Subscriber base class .cpp
void CServerCommandSubscriber::HandleServerCommand(const WPARAM wParam, const LPARAM lParam)
{
const Command cmd = static_cast<Command>(wParam);
switch (cmd)
{
case something:
OnSomething(SomethingData(lParam)); // Virtual method call
break;
case // ...
};
}
The problem is, that I see strange crashes in the HandleServerCommand() method:
It looks something like this:
Debug Error!
Program: c:\myprogram.exe
Module:
File: i386\chkesp.c
Line: 42
The value of ESP was not properly
saved across a function call. This is
usually the result of calling a
function declared with one calling
convention with a function pointer
declared with a different calling
convention.
I checked the function pointer that AfxBeginThread() wants to have:
typedef UINT (AFX_CDECL *AFX_THREADPROC)(LPVOID); // AFXWIN.H
static UINT AFX_CDECL MessageGeneratorThread(LPVOID pParam); // My thread function
To me, this looks compatible, isn't it?
I don't know, what else I have to look for. Any ideas?
I made another strange observation, that might be related:
In the NotifySubscribersmethod, I call IsWindow() to check if the window to which the handle points, exists. Apparently it does. But calling CWnd::FromHandlePermanent() returns a NULL pointer.
From afxmsg_.h:
// for Registered Windows messages
#define ON_REGISTERED_MESSAGE(nMessageVariable, memberFxn) \
{ 0xC000, 0, 0, 0, (UINT_PTR)(UINT*)(&nMessageVariable), \
/*implied 'AfxSig_lwl'*/ \
(AFX_PMSG)(AFX_PMSGW) \
(static_cast< LRESULT (AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM) > \
(memberFxn)) },
So the signature is LRESULT ClassName::FunctionName(WPARAM, LPARAM), while yours is void ClassName::FunctionName(const WPARAM, const LPARAM). This should not compile, at least under VS2008 it doesn't.
What is your HandleServerCommand declaration in the CServerCommandSubscriber class (in the header file)?
To me, this looks compatible, isn't
it?
Syntactically it looks that way.
I don't know, what else I have to look
for. Any ideas?
Yes: I've had the same problem when compiling a plugin library with debug settings and used in a Release-compiled application.
Basically, the problem looks like a stack corruption.
Since you're running NotifySubscribers in a separate thread, consider using PostMessage (or PostThreadMessage) instead of SendMessage.
This may not be the actual cause of the crash, but the change should be made anyway (as you're switching threading contexts by using SendMessage with no guarding of the data whatsoever.
I eventually decided to do it without window messages and am now posting my workaround here. Maybe it will help someone else.
Instead of letting the observer post window messages to its subscribers, I let the observer put data into synchronized subscriber buffers. The dialog class subscriber uses a timer to periodically check its buffers and call the apropriate handlers if those aren't empty.
There are some disadvantages:
It's more coding effort because for each data type, a buffer member needs to be added to the subscriber.
It's also more space consuming, as the data exists for each subscriber and not just once during the SendMessage() call.
One also has to do the synchronization manually instead of relying on the observer thread being suspended while the messages are handled.
A - IMO - huge advantage is that it has better type-safety. One doesn't have to cast some lParam values into pointers depending on wParam's value. Because of this, I think this workaround is very acceptable if not even superior to my original approach.