Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 960
  • Last Modified:

C++ CreateThread doesn't call function

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
MLeandroK
Asked:
MLeandroK
1 Solution
 
jkrCommented:
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
 
jkrCommented:
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
 
jkrCommented:
>>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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
rajeev_devinCommented:
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
 
AlexFMCommented:
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
 
MLeandroKAuthor Commented:
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
 
MLeandroKAuthor Commented:
And i almost forgot thanks for the answers.
Any futher suggestions on how to solve this?
0
 
waysideCommented:
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
 
MLeandroKAuthor Commented:
"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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Tackle projects and never again get stuck behind a technical roadblock.
Join Now