Solved

C++ CreateThread doesn't call function

Posted on 2006-07-16
9
845 Views
Last Modified: 2012-06-21
Hello,

i got a multithreaded dll compiled with Microsoft Visual C++ 6.
The code looks similar to this:

DWORD WINAPI oncommand(PVOID params)
{
      MessageBox(0, "test01", "test", 0);
}
BOOL APIENTRY DllMain(HANDLE hModule, DWORD reason, LPVOID lpReserved)
{
      unsigned long cthreadid;
      CreateThread(NULL, 0, &oncommand, 0, 0, &cthreadid);
      Sleep(10000);
}

When i compile this dll with the /MT parameter turned on, the desired messagebox doesn't pop up.
It seems, that the CreateThread function does for some odd reason not work.
Any suggestions on how to solve that?
0
Comment
Question by:MLeandroK
9 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 17119225
You are passing teh thread proc incorrectly, that should be

BOOL APIENTRY DllMain(HANDLE hModule, DWORD reason, LPVOID lpReserved)
{
     unsigned long cthreadid;
     CreateThread(NULL, 0, oncommand, 0, 0, &cthreadid); // *no* '&' with the thread proc
     Sleep(10000);
}

If you use the ampersand, you pass the address of the address of the function, that's why it does not work.
0
 
LVL 86

Expert Comment

by:jkr
ID: 17119239
As a side note, it's always good to check for errors when calling a Win32 API function, e.g. like

BOOL APIENTRY DllMain(HANDLE hModule, DWORD reason, LPVOID lpReserved)
{
     unsigned long cthreadid;
     HANDLE hThread = CreateThread(NULL, 0, oncommand, 0, 0, &cthreadid);
    if (!hThread) {

        char buf[256];

        wsprintf(buf,"Error creating thread, reason %d", GetLastError());
        MessageBox(0, buf, "test error", MB_OK);
    }
     Sleep(10000);
}

0
 
LVL 86

Expert Comment

by:jkr
ID: 17119287
>>If you use the ampersand, you pass the address of the address of the function, that's why it does not
>> work.

Just to be clear on that - in C/C++, the name of a function is equal to it's address, that's why that single ampersand before the name has caused things to go down the drain for the reason above.
0
Optimizing Cloud Backup for Low Bandwidth

With cloud storage prices going down a growing number of SMBs start to use it for backup storage. Unfortunately, business data volume rarely fits the average Internet speed. This article provides an overview of main Internet speed challenges and reveals backup best practices.

 
LVL 12

Expert Comment

by:rajeev_devin
ID: 17119538
The problem is not with the &. You can use both.
As jkr suggested the name of the function is sufficient as the function address.
But you can also append & before it.
The both values will be same.

Make sure that your DLL is not loaded before.
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 17119677
Remove Steep, replace MessageBox with TRACE or OutputDebugString and test this again. What result do you have?
BTW, thread should not be created in DllMain, you need to add exported function for this.
0
 

Author Comment

by:MLeandroK
ID: 17120808
I now tried both parameters &oncommand and oncommand without the & symbol, neither of them works.
I also appended the code
if (!hThread)
{
        char buf[256];
        wsprintf(buf,"Error creating thread, reason %d", GetLastError());
        MessageBox(0, buf, "test error", MB_OK);
}
as written by jkr, but hThread seems to have a value, consequently it doesn't enter the if-loop.
When i forced the content of the if-loop to be executed, the return of GetLastError() was equal to 0.

I should probably also add that the exact same code has worked (at least i'm pretty sure it was the same, unless code rewrites itself) and now suddenly doesn't.
So i personally think it's rather a compiler issue.
0
 

Author Comment

by:MLeandroK
ID: 17120818
And i almost forgot thanks for the answers.
Any futher suggestions on how to solve this?
0
 
LVL 14

Accepted Solution

by:
wayside earned 500 total points
ID: 17122072
How does your dll get loaded?

You should set a break-point in your thread function and see if it ever gets called.

If it does, check the return value from the MessageBox() call, if 0 use GetLastError() to see what the error is.

In general it is a Bad Idea to do anything substantive in DllMain(), especially if your dll is implicitly loaded.

Also, the MSDN page for CreateThread() says the following:

"During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is done for the process."

This clearly states that your thread won't run until DllMain() returns, which won't be until after your Sleep(10000) finishes. Are you waiting 10 seconds or are you killing your program right away when the message box doesn't appear?
0
 

Author Comment

by:MLeandroK
ID: 17122901
"This clearly states that your thread won't run until DllMain() returns"
this is the golden line i've been waiting for
thanks wayside, it works now.
0

Featured Post

NAS Cloud Backup Strategies

This article explains backup scenarios when using network storage. We review the so-called “3-2-1 strategy” and summarize the methods you can use to send NAS data to the cloud

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

803 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question