静态链接的情况不考虑,因为这种情况就是把所有代码合并到exe中,不需要进入点。
进入点就是系统在加载一个可执行代码块(主要是exe和dll)到内存的时候,系统将要调用的起始代码的位置。
加载分为启动时加载和运行时加载,这两种说法主要是针对dll的,因为exe加载必然会创建一个新的进程,所以exe加载都是启动时加载,就算是createprocess也应该说是启动时加载。而dll分为两种情况,第一种就是随着exe的加载一起加载到内存的同一进程地址空间中,另一种则是exe中的代码loadlibrary在运行时加载dll到当前exe的进程地址空间中。
无论上面哪种情况,只要加载,系统就会一定在加载的时候调用进入点代码,所以加载方式与进入点完全不影响。
win sdk文档中exe的进入点有两个,一个是main,另一个是winmain,这个进入点是可以改的,但是在c运行环境下,连接器一般把进入点默认设置为mainCRTStartup和WinMainCRTStartup,因为c运行时需要在代码执行前进行一些别的工作,所以就修改为前面两个c入口点,然后这两个函数再分别调用main和winmain。c运行时需要作的特别工作就是初始化c运行时环境,包括静态、全局变量和对象初始化。当main或者winmain返回时就又回到了前两个函数中,这两个函数的后半部分就是负责清理之前的初始化工作。
win sdk文档中的dll的进入店是dllmain,同样在c运行时下,改为_DllMainCRTStartup,系统加载dll时调用这个函数,然后这个函数做些初始化工作,再调用dllmain,然后返回_DllMainCRTStartup结束执行。此时,dll已经在进程的地址空间中了,该进程的exe可以使用dll中的代码了。如果该dll是启动时加载,那么在程序结束时会再次调用_DllMainCRTStartup进行清理之前dll初始化的工作,如果是通过loadlibrary来运行时加载dll,那么需要exe自己卸载dll,卸载的时候会再次调用_DllMainCRTStartup