Overclock.net › Forums › Software, Programming and Coding › Coding and Programming › Application Programming › [solved] Native C++: Passing events between software layers running on different threads. Help!
New Posts  All Forums:Forum Nav:

[solved] Native C++: Passing events between software layers running on different threads. Help!

post #1 of 5
Thread Starter 
rep+ and my eternal gratitude if you can help me come up with a good answer.

madsmiley.png I have been banging my head against a wall here trying to solve this...

The Backstory

I have a C# GUI that needs to use the functions from a project written in C++.

I am converting the original C++ program into a un-managed and unregistered C++ DLL. The C# GUI calls the C++ DLL. So far, that parts working just fine.

I am doing this software work as a contractor for a company. My code contains no proprietary information or company trade secrets, so i got permission from the engineering team to show as much of my code as you guys want to see. thumb.gif

( I can even give you the whole project, but it's 8 layers of software in 35+ files. )

I just graduated from college last year, and this is my first time doing C++. I am a n00b at C++, and have been teaching myself how to use it.

The Problem
The ORIGINAL C++ code uses MFC "ON_MESSAGE" for event handling. The bottom layer of software is running it it's own thread. It needs to notify the top layer that a event has happened.

The "ON_MESSAGE" command (from the original code) no longer works in my program, even though all the code relating to "on message" has been unchanged from the original code (I believe). The only thing I did was put the original code into a DLL, and remove some GUI elements. When I debug the code, I can watch the lower software layer send out the ON_MESSAGE event, but the top software layer never gets the message. Perhaps it could be related to the code running in a DLL? Do DLL's handle threading differently than native C++ applications?

I have asked the other software engineers, and none of them can figure out why my code does not work. After hours of trying, I gave up on ON_MESSAGE.

So I tried using the standard C++ event handling code given here --> http://msdn.microsoft.com/en-us/library/ee2k0a7d.aspx . The problem is, I can get this code to WORK on just one thread on just one layer. I can not get it to work when passing events between threads and layers.

Finally, I tried a finite state machine for the events. This works,.......but gobble up all the resources of the processor. So instead of firing instantly, ...it takes about 2 minutes for the event to fire. My "while" loop seems to be gobbling up my resources, but if i remove the "while" loop it only handles 1 event then stops. Is their any way to release the main thread that runs the while loop for a few milliseconds? or make it at the lowest priority?

I've been banging my head against a wall for half a week trying to solve this. Maybe someone can help me take 2 steps back and find a simple way to do this? Or maybe someone can find the fault in my original ON_MESSAGE code?

The ON_MESSAGE code I tried is as follows.. (These are really huge files. I am only showing the code that I believe is necessary. I can show more if you wish.)

Top layer

Top Layer .CPP file
BEGIN_MESSAGE_MAP(CPIC32UBLDlg, CDialog)
ON_MESSAGE(WM_USER_BOOTLOADER_RESP_OK, OnReceiveResponse)
ON_MESSAGE(WM_USER_BOOTLOADER_NO_RESP, OnTransmitFailure)
END_MESSAGE_MAP()

LRESULT CPIC32UBLDlg::OnReceiveResponse(WPARAM cmd, LPARAM RxDataPtrAdrs)
{
// Event handling code goes here
}

LRESULT CPIC32UBLDlg::OnTransmitFailure(WPARAM cmd, LPARAM)
{
// Event handling code goes here
}

Top Layer .H file
class CPIC32UBLDlg : public CDialog
{

protected:
DECLARE_MESSAGE_MAP()

public:
afx_msg LRESULT OnReceiveResponse(WPARAM, LPARAM);
afx_msg LRESULT OnTransmitFailure(WPARAM, LPARAM);
}

Bottom Layer

Bottom Layer .CPP file
void some_class :: some_function(void)
{
::PostMessage(m_hWnd, WM_USER_BOOTLOADER_NO_RESP, (WPARAM)LastSentCommand, 0 );
}

Bottom Layer .H file
#define WM_USER_BOOTLOADER_RESP_OK WM_USER+1
#define WM_USER_BOOTLOADER_NO_RESP WM_USER+2


The state machine i tried is as follows....(These are really huge files. I am only showing the code that I believe is necessary. I can show more if you wish.)

Top layer
while (1)
{
switch (Lower_layer_Class.state)
{
case OnTransmitFailure
{
// Event handling code goes here
break;
}
case OnReceiveResponse
{
// Event handling code goes here
break;
}
case default:
{
break
}
}

UPDATE: As of right now, I am giving up on my ON_MESSAGE code and While(1)-state-machine-thingy. I am going to give the event handler a second try. I am going to base my solution off the code presented here --> http://www.codeproject.com/Articles/2042/Using-events-for-thread-synchronization . I'll give you an update if I get it working. Still, feel free to post if you know of a easier way to solve my problem.
Edited by crimsontears809739 - 10/3/12 at 9:07am
Deus Ex Machina
(19 items)
 
   
CPUMotherboardGraphicsRAM
i5 580M Dell 0R1203 NVIDIA Quadro FX 2800M Samsung 4Gb 
Hard DriveHard DriveOptical DriveOS
TOSHIBA MK3256GSYF  TOSHIBA MK3256GSYF  DVD-Rom HL-DT-ST DVD+-RW GU40N Windows 7 Professional 
Audio
Dell Computer 5 Series/3400 Series Chipset Fami... 
CPUMotherboardGraphicsGraphics
Athlon 64 X2 6400+  Asus M2N-E Nforce 500 SLi 8800GT  9800 GT 
RAMHard DriveOptical DriveOS
OCZ ReaperX WD LG lightscribe Multilayer DVD burner Windows 7 
PowerCase
Antec 500W Smartpower 2.0 Aspire X-Navigator 
  hide details  
Reply
Deus Ex Machina
(19 items)
 
   
CPUMotherboardGraphicsRAM
i5 580M Dell 0R1203 NVIDIA Quadro FX 2800M Samsung 4Gb 
Hard DriveHard DriveOptical DriveOS
TOSHIBA MK3256GSYF  TOSHIBA MK3256GSYF  DVD-Rom HL-DT-ST DVD+-RW GU40N Windows 7 Professional 
Audio
Dell Computer 5 Series/3400 Series Chipset Fami... 
CPUMotherboardGraphicsGraphics
Athlon 64 X2 6400+  Asus M2N-E Nforce 500 SLi 8800GT  9800 GT 
RAMHard DriveOptical DriveOS
OCZ ReaperX WD LG lightscribe Multilayer DVD burner Windows 7 
PowerCase
Antec 500W Smartpower 2.0 Aspire X-Navigator 
  hide details  
Reply
post #2 of 5
Thread Starter 
Earlier i edited my thread to post a link to " Using events for thread synchronization ".

That code uses .net, which i can not use in a DLL. I think it was a step in the right direction.

Some-more digging and i found this --> http://www.codeproject.com/Articles/7953/Thread-Synchronization-for-Beginners

The reason why creating an event the first time did not work, is because I did not know about thread synchronization objects.

I am going to replace the "while (1)" loop with a Win32 Wait Function or a MFC Lock/Unlock Resource function to handle the events.

I think i am on the right track now. I still have a lot to figure out, but I feel this is the correct approach. Also, I feel bad for answering my own post.

Oftentimes the process of writing down my problem allows me to see it more clearly,.....then i end up answering my own question in my own thread. thumb.gif

I'll post another update once i get this working.
Deus Ex Machina
(19 items)
 
   
CPUMotherboardGraphicsRAM
i5 580M Dell 0R1203 NVIDIA Quadro FX 2800M Samsung 4Gb 
Hard DriveHard DriveOptical DriveOS
TOSHIBA MK3256GSYF  TOSHIBA MK3256GSYF  DVD-Rom HL-DT-ST DVD+-RW GU40N Windows 7 Professional 
Audio
Dell Computer 5 Series/3400 Series Chipset Fami... 
CPUMotherboardGraphicsGraphics
Athlon 64 X2 6400+  Asus M2N-E Nforce 500 SLi 8800GT  9800 GT 
RAMHard DriveOptical DriveOS
OCZ ReaperX WD LG lightscribe Multilayer DVD burner Windows 7 
PowerCase
Antec 500W Smartpower 2.0 Aspire X-Navigator 
  hide details  
Reply
Deus Ex Machina
(19 items)
 
   
CPUMotherboardGraphicsRAM
i5 580M Dell 0R1203 NVIDIA Quadro FX 2800M Samsung 4Gb 
Hard DriveHard DriveOptical DriveOS
TOSHIBA MK3256GSYF  TOSHIBA MK3256GSYF  DVD-Rom HL-DT-ST DVD+-RW GU40N Windows 7 Professional 
Audio
Dell Computer 5 Series/3400 Series Chipset Fami... 
CPUMotherboardGraphicsGraphics
Athlon 64 X2 6400+  Asus M2N-E Nforce 500 SLi 8800GT  9800 GT 
RAMHard DriveOptical DriveOS
OCZ ReaperX WD LG lightscribe Multilayer DVD burner Windows 7 
PowerCase
Antec 500W Smartpower 2.0 Aspire X-Navigator 
  hide details  
Reply
post #3 of 5
I'd have helped you if you put your code in code tags! tongue.gif
Just kidding - I only just saw the thread!

You could also use window messages (might not be thread safe), memory mapped files, named pipes... smile.gif

Another technique if you need to notify GUI code in C# from C++ (i.e. the opposite of P/Invoke) you can use delegates to talk to C# code from C++.
Ol' Sandy
(28 items)
 
"Zeus"
(12 items)
 
Elite Preview
(6 items)
 
CPUMotherboardGraphicsRAM
Intel Xeon E3-1230v3 Gigabyte GA-Z97X-UD5H-BK MSI Gaming GTX 980 Kingston 32GB (4x8) 
Hard DriveHard DriveHard DriveHard Drive
Plextor PX-256M5S 256GB Samsung EVO 1TB Hitachi HDS721010CLA332 Hitachi HDS723020BLA642 
Hard DriveHard DriveHard DriveOptical Drive
Hitachi HDS723020BLA642 Hitachi HUA722010CLA330 WDC WD10EARS-00Z5B1 TSSTcorp CDDVDW SH-S223B 
CoolingCoolingOSMonitor
Phanteks PH-TC14PE with TY-140's Lamptron FCv5 (x2) Windows 8 Pro 64-bit Dell U2412M 
MonitorMonitorMonitorKeyboard
Dell U2412M Dell U2212HM Dell U2713HM Topre Realforce 87UB | Ducky DK9087 G2 Pro 
PowerCaseMouseMouse Pad
Corsair AX-750 Corsair Obsidian 650D Logitech G700 XTRAC Ripper XXL 
AudioAudioAudioAudio
Beyerdynamic DT-770 Pro 250ohm Schiit Bifrost DAC Schiit Asgard 2 HiVi Swan M50W 2.1 
CPUMotherboardRAMHard Drive
Intel Xeon E5-2620 Super Micro X9SRL-F-B 128GB 1333MHz LSI 9271-8i 
OSPowerCase
VMware ESXi 5.5 SeaSonic SS-400FL2 Fractal Define R3 
CPUMotherboardGraphicsRAM
Intel Core i5-3437U HP EliteBook Folio 9470m  Intel HD Graphics 4000  16GB DDR3 SDRAM 
Hard DriveOS
256GB SSD Windows 10 Insider Preview 
  hide details  
Reply
Ol' Sandy
(28 items)
 
"Zeus"
(12 items)
 
Elite Preview
(6 items)
 
CPUMotherboardGraphicsRAM
Intel Xeon E3-1230v3 Gigabyte GA-Z97X-UD5H-BK MSI Gaming GTX 980 Kingston 32GB (4x8) 
Hard DriveHard DriveHard DriveHard Drive
Plextor PX-256M5S 256GB Samsung EVO 1TB Hitachi HDS721010CLA332 Hitachi HDS723020BLA642 
Hard DriveHard DriveHard DriveOptical Drive
Hitachi HDS723020BLA642 Hitachi HUA722010CLA330 WDC WD10EARS-00Z5B1 TSSTcorp CDDVDW SH-S223B 
CoolingCoolingOSMonitor
Phanteks PH-TC14PE with TY-140's Lamptron FCv5 (x2) Windows 8 Pro 64-bit Dell U2412M 
MonitorMonitorMonitorKeyboard
Dell U2412M Dell U2212HM Dell U2713HM Topre Realforce 87UB | Ducky DK9087 G2 Pro 
PowerCaseMouseMouse Pad
Corsair AX-750 Corsair Obsidian 650D Logitech G700 XTRAC Ripper XXL 
AudioAudioAudioAudio
Beyerdynamic DT-770 Pro 250ohm Schiit Bifrost DAC Schiit Asgard 2 HiVi Swan M50W 2.1 
CPUMotherboardRAMHard Drive
Intel Xeon E5-2620 Super Micro X9SRL-F-B 128GB 1333MHz LSI 9271-8i 
OSPowerCase
VMware ESXi 5.5 SeaSonic SS-400FL2 Fractal Define R3 
CPUMotherboardGraphicsRAM
Intel Core i5-3437U HP EliteBook Folio 9470m  Intel HD Graphics 4000  16GB DDR3 SDRAM 
Hard DriveOS
256GB SSD Windows 10 Insider Preview 
  hide details  
Reply
post #4 of 5
Thread Starter 
Quote:
Originally Posted by tompsonn View Post

I'd have helped you if you put your code in code tags! tongue.gif
Just kidding - I only just saw the thread!
You could also use window messages (might not be thread safe), memory mapped files, named pipes... smile.gif
Another technique if you need to notify GUI code in C# from C++ (i.e. the opposite of P/Invoke) you can use delegates to talk to C# code from C++.

Yeah...just learned about code tags yesterday. I will from now on. thumb.gif

This is embarrassing, but i was not chasing the real source of the problem. The REAL source of my problem my state-machine inside the "while" loop was not being reset (the state machine was not shown in my earlier example for sake of simplicity).

...leading me to come to some false conclusions about what my problem was.
Deus Ex Machina
(19 items)
 
   
CPUMotherboardGraphicsRAM
i5 580M Dell 0R1203 NVIDIA Quadro FX 2800M Samsung 4Gb 
Hard DriveHard DriveOptical DriveOS
TOSHIBA MK3256GSYF  TOSHIBA MK3256GSYF  DVD-Rom HL-DT-ST DVD+-RW GU40N Windows 7 Professional 
Audio
Dell Computer 5 Series/3400 Series Chipset Fami... 
CPUMotherboardGraphicsGraphics
Athlon 64 X2 6400+  Asus M2N-E Nforce 500 SLi 8800GT  9800 GT 
RAMHard DriveOptical DriveOS
OCZ ReaperX WD LG lightscribe Multilayer DVD burner Windows 7 
PowerCase
Antec 500W Smartpower 2.0 Aspire X-Navigator 
  hide details  
Reply
Deus Ex Machina
(19 items)
 
   
CPUMotherboardGraphicsRAM
i5 580M Dell 0R1203 NVIDIA Quadro FX 2800M Samsung 4Gb 
Hard DriveHard DriveOptical DriveOS
TOSHIBA MK3256GSYF  TOSHIBA MK3256GSYF  DVD-Rom HL-DT-ST DVD+-RW GU40N Windows 7 Professional 
Audio
Dell Computer 5 Series/3400 Series Chipset Fami... 
CPUMotherboardGraphicsGraphics
Athlon 64 X2 6400+  Asus M2N-E Nforce 500 SLi 8800GT  9800 GT 
RAMHard DriveOptical DriveOS
OCZ ReaperX WD LG lightscribe Multilayer DVD burner Windows 7 
PowerCase
Antec 500W Smartpower 2.0 Aspire X-Navigator 
  hide details  
Reply
post #5 of 5
Thread Starter 
double post, please delete me.
Edited by crimsontears809739 - 10/3/12 at 9:32am
Deus Ex Machina
(19 items)
 
   
CPUMotherboardGraphicsRAM
i5 580M Dell 0R1203 NVIDIA Quadro FX 2800M Samsung 4Gb 
Hard DriveHard DriveOptical DriveOS
TOSHIBA MK3256GSYF  TOSHIBA MK3256GSYF  DVD-Rom HL-DT-ST DVD+-RW GU40N Windows 7 Professional 
Audio
Dell Computer 5 Series/3400 Series Chipset Fami... 
CPUMotherboardGraphicsGraphics
Athlon 64 X2 6400+  Asus M2N-E Nforce 500 SLi 8800GT  9800 GT 
RAMHard DriveOptical DriveOS
OCZ ReaperX WD LG lightscribe Multilayer DVD burner Windows 7 
PowerCase
Antec 500W Smartpower 2.0 Aspire X-Navigator 
  hide details  
Reply
Deus Ex Machina
(19 items)
 
   
CPUMotherboardGraphicsRAM
i5 580M Dell 0R1203 NVIDIA Quadro FX 2800M Samsung 4Gb 
Hard DriveHard DriveOptical DriveOS
TOSHIBA MK3256GSYF  TOSHIBA MK3256GSYF  DVD-Rom HL-DT-ST DVD+-RW GU40N Windows 7 Professional 
Audio
Dell Computer 5 Series/3400 Series Chipset Fami... 
CPUMotherboardGraphicsGraphics
Athlon 64 X2 6400+  Asus M2N-E Nforce 500 SLi 8800GT  9800 GT 
RAMHard DriveOptical DriveOS
OCZ ReaperX WD LG lightscribe Multilayer DVD burner Windows 7 
PowerCase
Antec 500W Smartpower 2.0 Aspire X-Navigator 
  hide details  
Reply
New Posts  All Forums:Forum Nav:
  Return Home
  Back to Forum: Application Programming
Overclock.net › Forums › Software, Programming and Coding › Coding and Programming › Application Programming › [solved] Native C++: Passing events between software layers running on different threads. Help!