Richard Heathfield a écrit :
A DLL can contain many functions. In some DLLs, there is a DllMain
function which acts as the entry point. In others, there is not.
This is what you refuse to understand Mr Heathfield.
ALL dlls will be called BY THE LOADER before the program starts.
This is NOT a call y your user code, it is a call by the
operating system and you can't do anything to avoid it.
This call will be done to a special entry point called DllMain
in the literature but can be actually any function that is
defined as entry point by the user.
The loader finds the address to call by looking at the header
of the dll. For instance, in the dll you sent me, the header
has the entry point field with a value of 0x1220 (4640 decimal)
This means that the loader will call the address:
DLL load point + 4640.
This is the address of the DllMain procedure. Note that this
address will change, depending on the address the dll itself
is loaded.
This call has standard arguments, described in the documentation.
It will receive those argumùents that allow it to see WHY it was called.
There are 4 calls to the entry point of the dll:
1) Before starting the program. Here the dll can use this occasion
to initilize stuff
2) When a new thread is started. Here the dll can initilize things in
a per thread basis
3) When a thread ends. Here you can do the opposite of what you
did at (2).
4) Just before when the program ends. Here you do the opposite as (1).
In
such DLLs, any one of the functions within the DLL (that is not
static) may be used first (except when there are internal
programmer-specified constraints that are not relevant here - a point
that is a side issue but upon which I will expand if required).
This is correct, but has nothing to do with the calls
done not by your code but by the code of the operating
system (the system program loader)
Here's an example of how a DLL can have multiple entry points:
#include "dlldemo.h" /* I posted source for this, upthread */
#include <stdio.h>
int main(void)
{
int i = foo(6); /* I posted source for foo(), upthread */
printf("%d\n", i);
return 0;
}
Prints 3 and a newline. Clearly, the entry point for the DLL is foo()
on this occasion.
You are right that here the entry point is foo(). But, that has
nothing to dow with the entry point OF THE DLL.
On no occasion was any DllMain function called. Neither did such a
function exist.
The call to the entry point is transparent to you. Since you did NOT
define an entry point, the compiler supplied you automatically
an entry point function that returns always TRUE and does nothing.
Then, you do not see it.
You can convince yourself of that by making a DllMain function
that always returns ZERO. You will see that the system will
refuse to load your dll!
Here's the DLL binary (assuming my Web server is up - if not, just say
and I'll fix it):
http://www.cpax.org.uk/scratch/dlldemo.dll
and here's the import library:
http://www.cpax.org.uk/scratch/dlldemo.lib
In case you find them useful, here are the sources:
http://www.cpax.org.uk/scratch/dlldemo.c
http://www.cpax.org.uk/scratch/dlldemo.h
http://www.cpax.org.uk/scratch/dlldemo.def
No. If I'm wrong, I'd like to find out, please. But so far it has not
been shown that I'm wrong.
I use pedump.exe to dump dlls. Your dll has an entry point of
0x1220
Even if it's there, for which I can find no evidence, it still isn't
the entry point into user code.
Show me.
Look. One way to cinvince yourself that dllmain is called
before your program starts is to use the debugger
(1) Write a DllMain function
(2) make it to write
printf("hello world from the dll\n"
when it receives the message DLL_PROCCESS_ATTACH
(3) print as first line in your main() procedure
printf("hello world from main\n");
You should see first the message from the dll. Do not
forget to start the program from a console window.
Here is the code that you can cut/paste to do that:
int WINAPI LibMain(HINSTANCE hDLLInst, DWORD Reason, LPVOID Reserved)
{
switch (Reason)
{
case DLL_PROCESS_ATTACH:
printf("hello world from my dll!\n");
break;
case DLL_PROCESS_DETACH:
printf("The program is going to stop\n");
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
// Note that if you return zero, the progarm will not start
}
Note that I did not call the entry point DllMain but LibMain,
just to prove you that the name is USER DEFINED.