Link to home
Start Free TrialLog in
Avatar of CSecurity
CSecurityFlag for Iran, Islamic Republic of

asked on

DLLMain return a value but stay in memory and keep working

Hi

I'm creating a DLL, as you know DLL have a DLLMain function, it's getting fired when my application loads my DLL using LoadLibrary. But problem is here:

- App when calls LoadLibrary DLLMain in DLL get fired and DLL should create 3 thread and do some stuff
- in DLLMAin when I create threads I have WaitForMultipleObjects(handlearr, INFINITE)
- App hangs until I return and return a value from DLLMAIN



I tried creating a window and registering a timer, but window also needs a loop for GetMessage and TranslateMessage

So please advice. How my DLL can create threads do some stuff, but caller application will continue after LoadLibrary?

Please advice.
Thanks
ASKER CERTIFIED SOLUTION
Avatar of Knut Hunstad
Knut Hunstad
Flag of Norway image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of CSecurity

ASKER

As I said and as you said, I should create my threads in DLLMain but main program should not hang and should not wait for me...

I tried to achive it with creating a window and settings a timer, then timer fires a function and that function creates threads, but again after creating a window I should wait for messages like:

while (GetMessage(&msg, NULL, 0, 0))
      {
            if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
            {
                  TranslateMessage(&msg);
                  DispatchMessage(&msg);
            }
      }


How can I create threads, stay in memory but don't hang the caller APP?
Sorry, but I'm still not sure I see exactly what you are trying to do! Answering these questions might help:

1. Is your main app a Windows application?
2. Do you want that to create some threads, living "on their own"?
3. Will these threads be communicating with the main app by sending windows messages?
4. Did you create this window in your main app or in one of the threads?
5. The function that creates thread, is that still using WaitForMultipleObjects with INFINITE?
6. Did you use Cwnd::SetTimer to create your timer?

If the answer to 1-3, 5 and 6 is "yes" and to 4 "the main app", then I think your problem is: Your main app has a message loop. This receives a message, sent out by a timer (Cwnd::SetTimer sends a WM_TIMER message at the specified time(s)). The message loop enters the function specified by the SetTimer call, but still in the main app thread! This function creates threads and waits for them INFINITEly. That means your main app will be waiting for all the threads to finish.

Note that a message loop is still only sequential code in one thread. When your main app's message loop receives the timer message, the main thread will go into your function. It does not start a new thread for handling the message. So if this function gets locked (because it started some threads and is waiting for them to finish), your main app (and thereby your message loop) will get locked.

Hope this helps? Sorry if I've just repeated things you already knew and the problem is something else :-)
Timer and creating window all is in DLL not in Main program

I want to do a lot of things, creating threads (about 10) and do a lot of jobs just after getting loaded in DLL.

I cannot do a lot of things, create threads and stay in memory just with gettings loaded by LoadLibrary. Because caller app hangs.

It's my problem!
OK, let's try another question: why do you have WaitForMultipleObjects in your DLLMain at all, if you _don't_ want to wait for the threads to finish?

Let me guess again (although I haven't guessed very successful so far :-)

If you want the DLLMain to exist in it's own thread (because you have something you want done after all the other threads are finished), you need to either:

- fork in DLLMain, letting the child wait for the threads and the parent to continue (as the main app).
- start one thread in DLLMain (and not wait for it), with a function that starts the other threads and waits for them to finish.
this one:

- start one thread in DLLMain (and not wait for it), with a function that starts the other threads and waits for them to finish.

how it's possible, if I don't wait for them, threads exists
The threads will normally start running as soon as you create them (with CreateThread or whatever you use). The only thing WaitForMultipleObjects does, is wait for the threads to _finish_. That's why this call will lock things in your app.

So you don't need WaitForMultipleObjects at all if you just want to create your threads and let them live their own life.

If you're still in doubt, tell more about how you create your threads.
Thanks, let me check it out
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I don't think that thread creation should be done in DllMain.

Unlike main or WinMain it is an optional entry point for a dll and it could be called from system in the startup phase where not all (other) dlls already were loaded.

MSDN says:
----------------------------
Warning  The entry-point function should perform only simple initialization or termination tasks. It must not call the LoadLibrary or LoadLibraryEx function (or a function that calls these functions), because this may create dependency loops in the DLL load order. This can result in a DLL being used before the system has executed its initialization code. Similarly, the entry-point function must not call the FreeLibrary function (or a function that calls FreeLibrary), because this can result in a DLL being used after the system has executed its termination code.
-----------------------------

Moreover, it was called upon FreeLibrary as well, so it is not a only-once-called function.

Better put the thread creation  into the application and pass a thread function (pointer) which you gained from dll by calling GetProcAddress. That way you could store the thread id into an array and manage threads properly in the app.
 
You are correct, of course, I should have seen that. But I don't think that's the reason for the problem here.

It's still possible to let the dll handle all threads. But let the DLLMain do as little as possible and let another function in the DLL take care of this. So first call LoadLibrary, then call into the function you want to create threads.
Honestly my DLL will be a plugin and another program will load it. But that program hangs when tries to load my plugin.

But my plugin should create a lot of threads and do a lot of jobs and I only getting loaded by main program easily with LoadLibrary which main program executes. How can I create a lot of threads and do a lot of things just when I got loaded?

Main program never calls FreeLibrary except if main program going to be closed, so I should get loaded and stay in memory, do a lot of things, and get unloaded only when main program unloaded

Please advice
OK, now the problem is clearer! You want things in your dll to start happening automatically upon loading the dll with LoadLibrary.

Take a look at: http://www.microsoft.com/whdc/driver/kernel/DLL_bestprac.mspx. It is _possible_ to create threads in DllMain, but dangerous. This paper should help you avoid the pitfalls!

But start with making really sure this is what you need! Having the application first call LoadLibrary and then some init-function in your dll will be a lot better!
SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>>>> Honestly my DLL will be a plugin and another program will load it. But that program hangs when tries to load my plugin.

The second is cause you wait for the threads to terminate in dllmain. That is the cause for the blocking and khun explained it clearly (and sufficiently IMO).

If it is a plugin it should offer some kind of user interface like menu entries, buttons, right-click menus, ... It rarely should run in the initialization phase of the hooked application. For example I recently wrote a plugin for acrobat which was loaded by acrobat when I firstly invoke the acrobat via COM. Then, I call the menu function installed with my plugin to actually invoke the needed functionality, in my case to create a pdf from different sources . A plug-in which doesn't work as a service and not only runs on request, isn't a plugin but in the best case a hook and in the worsest case a virus. Could you explain more clearly what you were trying to do? We surely could point a better solution then.
Thanks to all. Problem solved!