进程与windows应用程序

进程

      一般进程可以定为一个正在运行的程序的一个实例,
      一个内核对象,操作系统可以用它来管理进程。也是系统保存进程统计信息的地方。
      一个地址空间,其中包含了可执行文件和DLL模块的代码数据,同时包括动态内存分配,和线程堆栈和堆得分配。
      CPU的工作方式,是 一个进程可以有多个线程..然后CPU会轮流调度资源分配给各个线程,就像一个时钟一样。
     
关于Windows应用程序的组成

要点描述:

     1. GUI 和 CUI 分别表示 图形和控制台的界面,
     2./SUBSYSTEM:CONSOLE 和 /SUB-SYSTEM:WINDOWS 分别是控制台和窗口的链接器开关
     3._tWinMain 图形界面的入口点函数 和 _tmain 控制台界面的入口点函数。

一、Windows一般可以建立两种应用程序。
      1.GUI程序 - 图形用户界面 - 它使用的连接器开关是/SUBSYSTEM:CONSOLE
      2.CUI程序 - 控制台界面 - 它使用的连接器开关是/SUB-SYSTEM:WINDOWS
      操作系统会加载并检查可执行文件映像的文件头,并获取这个子系统值。
      根据子系统值来创建 一个符合要求的程序界面。
     
二、 Windows 应用程序 都会有个入口点函数,在程序运行时,函数会被调用。
     
      int WINAPI _tWinMain(
          HINSTANCE hInstanceExe,
          HINSTANCE,
          PTSTR pszCmdLine,
          int nCmdShow);

     int _tmain(
         int argc,
         TCHAR *argv[],
         TCHAR *envp[]);
        
         操作系统实际并不调用我们所写的入口点函数。相反,它会调用由C/C++运行库实现并链接时使用-entry:命令选项来设置
         的一个C/C++运行时启动函数。该函数将初始化C/C++运行库,使我们能调用malloc和free之类函数。
        
       应用程序类型和相应的入口点函数表

应用程序类型

入口点函数(入口)

嵌入可执行文件的启动函数

处理ANSI字符和字符串的GUI应用程序

_tWinMain (WinMain)

WinMainCRTStartup

处理Unicode字符和字符串的GUI应用程序

_tWinMain (wWinMain)

wWinMainCRTStartup

处理ANSI字符和字符串的CUI应用程序

_tmain (Main)

mainCRTStartup

处理Unicode字符和字符串的CUI应用程序

_tmain (Wmain)

wmainCRTStartup

       
       当链接器正确选择了C/C++运行库启动函数后,链接器会根据指定的链接器开关,寻找相应的入口点函数,否则会返回
       "unresolved external symbol"(无法解析的外部符号)错误。 不然一般会根据情况分别选择 嵌入可执行文件的启动函数。
      
       当然我们也可以从自己的项目中移除/SUBSYSTEM链接器开关,让程序自动判断应该使用哪个子系统。
       去启动入口点函数 (WinMain, wWinMain, main, or wmain) 。
      
       VisualC++有自带C运行库的源码。可以在ertex.c文件中找到 这4个启动入口点函数源代码。这些启动函数的用途下面简单说下:
       1.获取指向心进程的完整命令行的一个指针。
       2.获取指向新进程的坏境变量的一个指针。
       3.初始化C/C++运行库的全局变量。如果包含了StdLib.h,我们的代码就可以访问这些变量。
       4.初始化C运行库内存分配函数malloc和calloc和其他底层I/O历程使用的堆。
       5.调用所有全局和静态C++类对象的构造函数。
      

变量名称

类型

描述和推荐使用的Windws函数

_osver

unsigned int

操作系统构建的版本号, 如Windows Vista RTM was build 6000. 所以, _osver 的值就是6000. 请换用 GetVersionEx.

_winmajor

unsigned int

以十六进制表示的Windows系统的主版本. 对于Windows Vista,该值为6. 请换用GetVersionEx.

_winminor

unsigned int

以十六进制表示的Windows系统的主版本. 对于Windows Vista,该值为0. 请换用GetVersionEx.

_winver

unsigned int

(_winmajor << 8) + _winminor. 请换用GetVersionEx.

__argc

unsigned int

命令行上传递的参数个数. 请换用 GetCommandLine .

__argv

__wargv

char

wchar_t

长度为 __argc 的一个数组 ,其中含有指向 ANSI/Unicode 字符串指针.

数组中的每一项都指向一个命令行参数. 注意,如果定义了_UNICODE,__argv 就为 NULL如果没有定义__wargv 为 NULL 请换用 GetCommandLine.

_environ

_wenviron

char

wchar_t

一个指针数组,这些指针指向ANSI/Unicode字符串. 数组中的每一项都指向一个环境字符串. 注意,如果没定义_UNICODE ,_wenviron 就为 NULL如果已经定义了_UNICODE, _environ is NULL。请换用GetEnvironmentStrings 或 GetEnvironmentVariable

_pgmptr

_wpgmptr

char

wchar_t

正在运行的程序的名称及其ANSI/Unicode完整路径.

注意,如果已经定义了 _UNICODE ,_pgmptr is NULL如果没有定义——UNICODE,_wpgmptr is NULL 请换用GetModuleFileName, 将 NULL 作为第一个参数传给该函数。

       
       

   

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

C/C++启动函数会调用应用程序的入口点函数。比如我们写了一个_tWinMain函数,且定义了_UNICODE
其调用过程如下:
       GetStartupInfo(&StartupInfo);
       int nMainRetVal = wWinMain((HINSTANCE)&__ImageBase, NULL, pszCommandLineUnicode,
        (StartupInfo.dwFlags & STARTF_USESHOWWINDOW)
         ? StartupInfo.wShowWindow : SW_SHOWDEFAULT);

       如果没有定义_UNICODE,其调用过程将如下所示:
       GetStartupInfo(&StartupInfo);
       int nMainRetVal = WinMain((HINSTANCE)&__ImageBase, NULL, pszCommandLineAnsi,
       (StartupInfo.dwFlags & STARTF_USESHOWWINDOW)
      ? StartupInfo.wShowWindow : SW_SHOWDEFAULT);

       注意_ImageBase是一个链接器定义的伪变量,可执行文件都被映射到应用程序内存中的什么位置以后讨论。
      
       现在 我们如果写了一个_main函数,可以定义?_UNICODE其调用过程如下:
       int nMainRetVal = wmain(argc, argv, envp);
       没定义_UNICODE,调用过程如下:
       int nMainRetVal = main(argc, argv, envp);
      
       另外注意用Visual Studio 生成的应用程序CUI是没有入口点的第3个参数
       int _tmain(int argc, TCHAR* argv[]);
       要自己添加成
       int _tmain(int argc, TCHAR* argv[], TCHAR* env[])
       env参数指向一个参数,所有环境变量和值 都用等号(=)分隔。

    为安全起见 Microsoft 并不赞成使用所有这些变量,因为使用了这些变量代码可能会在C运行库初始化这些变量之前开始执行,因此我们应该直接调用对于的WindowsAPI函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值