Windows学习——进程(一)

进程

在C/C++所编写的程序中,我们所看到的主函数并不是程序一开始执行的函数,它也只是一个函数,而我们常用的就是命令行主函数入口也就是main,而Windows程序中还有一个主函数入口,就是下面所述

Int WINAPI _tWinMain(
    HINSTANCE hInstanceExe,
    HINSTANCE,
    PTSTR pszCmdLine,
    int nCmdShow);

我们常用的命令行入口原型如下:

int _tmain(
    int argc,
    TCHAR* argv[],
    TCHAR* envp[]);

而在进入主函数之前,需要对环境做一些初始化之内的工作,这些工作是交给启动函数去做的,启动函数有几个用途如下:

1.获取指向新进场的完整命令行的一个指针

2.获取指向新进场的环境变量的一个指针

3.初始化C/C++运行库的全局变量。如果包含了StdLih.h,我们的代码就可以访问这些变量。可以通过GetVersionEx、GetCommandLine、GetEnvironmentString、GetEnvironmentVariable、GetModuleFileName等函数获取这些全局变量的值

4.初始化C运行库内存分配函数和其他底层I/O例程使用的堆

5.调用所有全局和静态C++类对象的构造函数

 

入口点函数返回后,启动函数将调用C运行库函数exit,向其传递返回值(nMainRetVal)。exit函数会执行以下任务:

1.调用_onexit函数调用所注册的任何一个函数

2.调用所有全局和静态C++类对象的析构函数

3.在DEBUG生成中,如果设置了_CRTDBG_LEAK_CHECK_DF标志,就通过调用_CrtDumpMemoryLeaks函数来生成内存泄露报告

4.调用操作系统的ExitProcess函数,向其传入nMainRetVal。这回导致操作系统“杀死”我们的进程,并设置它的推出代码。

进程实例句柄

先说明一下HINSTANCE类型和HMODULE类型这两种参数是一样的,之所以取不一样的名字,这要从16位WIndows说起(网上找找)

HMODULE GetModuleHandle(PCTSTR pszModule);

调用这个函数时,要传递一个以0位终止符的字符串,它指定了已在主调进程的地址空间中加载的一个可执行文件或DLL文件的名称。如果系统找到了指定的可执行文件或DLL文件名称,GetModuleHandle就会返回可执行文件/DLL文件映象加载到的基地址,如果没有则返回null,还有一种用法就是,传进NULL值,可以返回主调进程的可执行文件的基地址。

示例:如果我们的代码在一个DLL中,那么可利用两种方法来了解代码正在什么模块中运行。

第一个方法是利用链接器提供的伪变量_ImageBase,它执行当前正在运行的模块的基地址。如前所述,这是C运行库启动代码在调用我们的WinMain函数时所作的事情

第二方法调用GetModuleHandleEx,将GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS作为他的第一个参数,将当前函数的地址作为第二个参数。最后一个参数时一个执行HMOUDLE的指针,GetModuleHandleEx会传入函数所在DLL的基地址来填写该指针

GetModuleHandleEx函数的两大重要特性:

1.它只检查主调进程的地址空间。如果主调进程没有使用任何通用对话框函数,那么一旦调用该函数,比向其传递ComDlg32,就会导致返回NULL

2.向其传递NULL值,会返回进程的地址空间中的可执行文件的基地址。所以即使是DLL中运行,返回值仍然是可执行文件的基地址,而非DLL文件的基地址

posted @ 2020-05-14 20:03  PYozo_free  阅读(207)  评论(0编辑  收藏  举报