Click here to Skip to main content
15,885,216 members
Please Sign up or sign in to vote.
4.50/5 (2 votes)
Hi All,

This is a long shot but after 2 days of coding I figure I'm unable to fix my problem, which is...

I have a C# GUI that references a C++ .NET DLL (managed) that makes calls to underlying C++ (unmanaged) DLL's. One of the methods in my C++ .NET DLL starts a thread that calls to my underlying C++ DLL, that code looks like this:

MIDL
m_oThread = gcnew Thread(gcnew ParameterizedThreadStart(this, &MyClass::MethodToRunOnThread));
m_oThread->Start(MyParameter);


MIDL
void MyClass::MethodToRunOnThread(Object^ step)
{ //Call to underlying C++ DLL (unmanaged).
}


The problem is my underlying DLL calls CWinThread::PumpMessage, and my app crashes when I hit that line. It feels like some kind of timing/locking problems because if I step the code as opposed to running it it sometimes gets past that line.

To add more confusion, if I make the call to my underlying C++ DLL without putting it on it's on thread it runs fine, i.e.

MIDL
MethodToRunOnThread(MyParameter);


I hope I've provided enough info to get you peeps thinking!
Regards,
Chris
Posted
Updated 14-Feb-11 4:26am
v3
Comments
Rajesh R Subramanian 11-Feb-11 9:22am    
Please modify your question to include the following two pieces of information.

1. Can you show me how exactly are you making the call to the native dll?
2. What exactly is the DLL doing?
Stephen Hewitt 11-Feb-11 9:44am    
What is the crash? What type of exception is generated?
Sergey Alexandrovich Kryukov 11-Feb-11 12:41pm    
Do the following: 1) catch exception (in managed code), in the catch make exception dump, include exception stack and all inner exceptions (recursive), 2) output the dump in some text file and post it here, 3) in exception stack find relevant line numbers and code files; 4) figure out part of code related to the exception and post it.

--SA
cr101037 14-Feb-11 6:37am    
Rajesh R Subramanian:
1. This is how I make the call to my unmanaged DLL...

void MyClass::MethodToRunOnThread(Object^ step)
{
MyUnmanagedClassInDLL* pointer = NULL;

BOOL bReturn = TRUE;
bReturn = pointer->MyMethod(); //this method eventually calls CWinThread::PumpMessage where it hangs!
}

2. The DLL communicates with another piece of software (through sockets).



Stephen Hewitt:
The app doesn't crash and there is no exception.




SAKryukov:
There is no exception to catch.


Just to recap, my app only hangs when I call my managed DLL on a seprearte thread! i.e. this hangs...

m_oThread = gcnew Thread(gcnew ParameterizedThreadStart(this, &MyClass::MethodToRunOnThread));
m_oThread->Start(MyParameter);

...and this doesn't...

MethodToRunOnThread(MyParameter);
Nish Nishant 14-Feb-11 10:26am    
Added C++/CLI tag to thread.

I suspect the problem is that your worker thread does not have a message loop. So you should not be calling PumpMessage from it. One thing you could try, if you can't clean up the code easily, is to call PeekMessage first to check for messages before calling PumpMessage.

[Edit]
~~~~~~~

Instead of creating a managed worker thread, try creating a UI thread using MFC's threading options. It seems the MFC code you call rely on the assumption that it's being called in a UI thread. That may fix your problem.

[Edit 2]
~~~~~~~~~

In response to your comment: Yes, but create the MFC thread from an unmanaged block (using #pragma unmanaged) and then have a managed method call the unmanaged function that creates the MFC thread. That should work for you.
 
Share this answer
 
v3
Comments
cr101037 14-Feb-11 9:49am    
Hi Nishant Sivakumar, thanks for your response.
Something I've just noticed, if I put a breakpoint on my PumpMessage() line and step into, it takes me here:

//thrdcore.cpp
BOOL CWinThread::PumpMessage()
{
return AfxInternalPumpMessage();
}

If I step over the "return AfxInternalPumpMessage();" line my app runs fine!?
It feels like some kind of timing/locking problem!
Nish Nishant 14-Feb-11 9:53am    
No, it's not a timing issue here. PumpMessage should not be called on a worker thread that does not have a message loop. You are creating a non-UI thread but the unmanaged code you call expects to be running on an UI thread.
Nish Nishant 14-Feb-11 9:54am    
Instead of creating a managed worker thread, try creating a UI thread using MFC's threading options. It seems the MFC code you call rely on the assumption that it's being called in a UI thread. That may fix your problem.
cr101037 14-Feb-11 10:00am    
Like the idea but is it possible to create an MFC UI Thread from managed code?
Nish Nishant 14-Feb-11 10:05am    
Yes, but create the MFC thread from an unmanaged block (using #pragma unmanaged) and then have a managed method call the unmanaged function that creates the MFC thread. That should work for you.
If everything is related to the PumpMessage call, then can't you just remove the call?

Are you doing the call on the current thread or the main app's thread? In the former case, there shouldn't be any problem, but in the later you would be pumping the main thread's messages from 2 different threads... it would lead to some unexpected results.
 
Share this answer
 
Comments
cr101037 14-Feb-11 9:35am    
Hi Olivier Levrey, the underlying unmanaged code is part of an existing system and I'm not able to modify it. My task was to simply remove the MFC UI and replace it with managed code.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900