第三篇 使用自己的函数替换C run-time启动函数

一 基本概念
     C运行时库给我们提供必要的库函数,如memcpy, printf, malloc等;它还提供的另外一个重要就是为应用程序添加启动函数。而C运行时库启动函数的主要功能为进行程序的初始化,对全局变量进行赋初始值,加载用户程序入口函数。
     平时的所谓入口函数WinMain()右C run-time 库中的 void WinMainCRTStartup(void)函数调用,在默认情况下,这个才是真正的入口点函数(在不采用宽字符集的情况下)。可以在VC安装目录中的CRT/SRC/CRT0.c原代码文件中看到该函数定义。
     在默认情况下,link程序连接了C 运行时库的某一个, 并且将函数mainCRTStartup(), wmainCRTStartup(), WinMainCRTStartup(), wWinMainCRTStartup()中的一个作为缺省的入口函数,可以根据link命令行中指定的子系统进行选择。 
      而自己的vc程序的入口点函数可以在编译器以便宜选项的方式指定,它可以使符合下面的形式的任何名称的函数:
      void _cdecl EntryName(void) ;
 
二 mainCRTStartup() 函数分析
     以下是经过别人简化后的入口函数代码。
 

#undef _UNCODE

void WinMainCRTStartup (void)

{

int mainret;

 

STARTUPINFO StartupInfo;

_osver = GetVersion ();

 

_winminor = (osver >>8) & 0x00FF;

_winmajor = _osver & 0x00FF;

_winver = (winmajor << 8) + _winminor;

osver = (osver >> 16) & 0x00FFFF;

 

if (!_heap_init (1))

fast_error_exit (_RT_HEAPINIT);

 

_acmdln = (char*) GetCommandLineA ();

_aenvptr = (char*) __crtGetEnvironmentStringsA ();

_setargv ();

_setenvp ();

 

_cinit ();

 

StartupInfo.dwFlags = 0;

GetStartupInfo (&StartupInfo);

 

mainret = WinMain (GetModuleHandleA (NULL),

NULL,

;pszCommandLine,

StartupInfo.dwFlags & STARTF_USESHOWWINDOWS ?

StartupInfo.wShowWindow : SW_SHOWDEFAULT);

 

exit (mainret);

}

      运行时库在调用用户程序的main或者WinMain函数前,首先进行初始化工作。只有首先进行进行初始化工作,我们的C 运行时库和应用程序才能正确工作。其具体代码含义如下:
      !获取操作系统的版本信息,用于以后操作
      !进行初始化进程堆栈
      !获取命令行,获取和设置环境变量
      !C运行时内部变量初始化
      ! 调用标准win32入口函数
      !  调用ExitProcess函数退出应用程序, 退出代码是WinMain的返回值
     
      除了crt0.c, C运行时库还包含wcrt0.c, wincrt0.c , wwincrt0.c 三个文件用来提启动函数。 wcrt0.c是crt0.c的宽字符集版,wincrt0.c中包含windows应用程序的入口函数,而wwincrt0.c则是wincrt0.c的宽字符集版。
 
三 使用自定义函数代替C run-time中的启动函数
      首先建立原代码文件init.c,在其中定义自己的启动函数 void entry (void)。代码如下所示:

#include<windows.h>
void entry (void)
{
    char** p;
    char* pAlloc ;
    int i;
    char * pszNames[]={
  "master",
   "Kai Ma",
   "John",
   "QQ",
   NULL
    } ;
 p=pszNames;
    for (i=0; p[i]!=NULL; i++)
    {
        MessageBox(NULL, p[i],"good",MB_OK) ;
    }
}

   编译程序:cl init.c /c

   连接目标文件:link init.obj /SUBSYSTEM:WINDOWS /OUT: init.exe /ENTRY: "entry" /NODEFALUTLIB kernel32.lib user32.lib
   这个程序使用了kernel32.lib user32.lib,但是在连接选项中指定了自己的入口函数,因此没有使用c 运行时库,也没有使用通常的入口函数 main /WinMain。 但是这个程序完全可以执行,是个标准的win32程序。
   
    如果要在vc6集成环境中编译连接这个程序,需要的设置如下:在c/c++页下设置编译选项/nologo /c,其他选项都删除;在link标签下的文本框设置连接选项为:/SUBSYSTEM:WINDOWS /OUT: init.exe /ENTRY: "entry" /NODEFALUTLIB kernel32.lib user32.lib 。然后编译执行。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值