⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 crtexe.c

📁 C语言库函数的原型,有用的拿去
💻 C
📖 第 1 页 / 共 2 页
字号:
/***
*crtexe.c - Initialization for console EXE using CRT DLL
*
*       Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
*       This is the actual startup routine for apps linking to the CRT DLL.
*       It calls the user's main routine [w]main() or [w]WinMain after
*       performing C Run-Time Library initialization.
*
*       With ifdefs, this source file also provides the source code for:
*       wcrtexe.c   the startup routine for console apps with wide chars
*       crtexew.c   the startup routine for Windows apps
*       wcrtexew.c  the startup routine for Windows apps with wide chars
*
*******************************************************************************/

#ifdef CRTDLL

/*
 * SPECIAL BUILD MACROS! Note that crtexe.c (and crtexew.c) is linked in with
 * the client's code. It does not go into crtdll.dll! Therefore, it must be
 * built under the _DLL switch (like user code) and CRTDLL must be undefined.
 * The symbol SPECIAL_CRTEXE is turned on to suppress the normal CRT DLL
 * definition of _fmode and _commode using __declspec(dllexport).  Otherwise
 * this module would not be able to refer to both the local and DLL versions
 * of these two variables.
 */

#undef  CRTDLL
#ifndef _DLL
#define _DLL
#endif  /* _DLL */

#define SPECIAL_CRTEXE

#include <cruntime.h>
#include <oscalls.h>
#include <internal.h>
#include <process.h>
#include <math.h>
#include <rterr.h>
#include <stdlib.h>
#include <tchar.h>
#include <rtcapi.h>
#include <sect_attribs.h>
#include <locale.h>

#ifdef _M_IA64
#pragma section(".base", long, read)
__declspec(allocate(".base"))
#endif  /* _M_IA64 */
extern IMAGE_DOS_HEADER __ImageBase;

/*
 * This has been moved from unhandld.cpp to here because, we only
 * want to set the UnhandledExceptionFilter when this crt is loaded
 * by an EXE (ie. not loaded by a DLL)
 */
int  __cdecl __CxxSetUnhandledExceptionFilter(void);
_CRTALLOC(".CRT$XIY") static _PIFV pinit = &__CxxSetUnhandledExceptionFilter;

#define SPACECHAR   _T(' ')
#define DQUOTECHAR  _T('\"')

/* default floating point precision - X86 only! */

#ifdef _M_IX86
extern void _setdefaultprecision();
#endif  /* _M_IX86 */


/*
 * Declare function used to install a user-supplied _matherr routine.
 */
_CRTIMP void __setusermatherr( int (__cdecl *)(struct _exception *) );


/*
 * Declare the names of the exports corresponding to _fmode and _commode
 */
#ifdef _M_IX86

#define _IMP___FMODE    _imp___fmode
#define _IMP___COMMODE  _imp___commode

#else  /* _M_IX86 */

/* assumed to be IA64 or x64 */

#define _IMP___FMODE    __imp__fmode
#define _IMP___COMMODE  __imp__commode

#endif  /* _M_IX86 */

extern int * _IMP___FMODE;      /* exported from the CRT DLL */
extern int * _IMP___COMMODE;    /* these names are implementation-specific */

extern int _fmode;          /* must match the definition in <stdlib.h> */
extern int _commode;        /* must match the definition in <internal.h> */
extern int _dowildcard;     /* passed to __getmainargs() */

#ifdef _M_IX86
/*
 * Declare/define communal to disable heap termination on corruption
 */
int _NoHeapEnableTerminationOnCorruption;
#endif  /* _M_IX86 */

/*
 * Declare/define communal that serves as indicator the default matherr
 * routine is being used.
 */
int __defaultmatherr;

/*
 * routine in DLL to do initialization (in this case, C++ constructors)
 */
extern int __cdecl _initterm_e(_PIFV *, _PIFV *);
extern void __cdecl _initterm(_PVFV *, _PVFV *);

/*
 * routine to check if this is a managed application
 */
static int __cdecl check_managed_app(void);

/*
 * pointers to initialization sections
 */
extern _CRTALLOC(".CRT$XIA") _PIFV __xi_a[];
extern _CRTALLOC(".CRT$XIZ") _PIFV __xi_z[];    /* C initializers */
extern _CRTALLOC(".CRT$XCA") _PVFV __xc_a[];
extern _CRTALLOC(".CRT$XCZ") _PVFV __xc_z[];    /* C++ initializers */

/*
 * Pointer to callback function to initialize any dynamically initialized
 * __declspec(thread) variables.  This relies on a subtle aspect of C.
 * The pointer is defined here uninitialized.  It is defined initialized in
 * tlsdyn.c.  If user code uses dynamically initialized __declspec(thread)
 * variables, then compiler-injected dependencies cause tlsdyn.obj to be
 * linked.  In that case, the non-zero definition of __dyn_tls_init_callback
 * in tlsdyn.obj will take precedence, and the startup code will execute the
 * callback.  This use of multiple definitions is only legal in C, not C++.
 */

const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback;

/*
 * Pointers to beginning and end of the table of function pointers manipulated
 * by _onexit()/atexit().  The atexit/_onexit code is shared for both EXE's and
 * DLL's but different behavior is required.  These values are set to -1 to
 * mark this module as an EXE.
 * NOTE - the pointers are stored encoded.
 */

extern _PVFV *__onexitbegin;
extern _PVFV *__onexitend;

/*
 * All the below variables are made static global for this file. This facilitates
 * in communicating mainCRTStartup and initialization code. Along with making these
 * variables global, two new functions are created pre_c_init, pre_cpp_init. The functions
 * are executed before anything in c_init and cpp_init sections repsectively.
 */

static int argc;   /* three standard arguments to main */
static _TSCHAR **argv;
static _TSCHAR **envp;

static int argret;
static int mainret=0;
static int managedapp;
static int has_cctor = 0;
static _startupinfo    startinfo;

static int __cdecl pre_c_init(void);
static void __cdecl pre_cpp_init(void);

_CRTALLOC(".CRT$XIAA") static _PIFV pcinit = pre_c_init;
_CRTALLOC(".CRT$XCAA") static _PVFV pcppinit = pre_cpp_init;

/***
*pre_c_init(void)
*
*Purpose:
*       The code in mainCRTStartup that was executed before executing C
*       initializers was shifted in this function. Also this funciton is the
*       first thing that is executed in c init section.
*
*Entry:
*
*Exit:
*
*******************************************************************************/

static int __cdecl pre_c_init(void)
{
    /*
     * Determine if this is a managed application
     */
    managedapp = check_managed_app();

    /*
     * Set __app_type properly
     */
#ifdef _WINMAIN_
    __set_app_type(_GUI_APP);
#else  /* _WINMAIN_ */
    __set_app_type(_CONSOLE_APP);
#endif  /* _WINMAIN_ */

    /*
     * Mark this module as an EXE file so that atexit/_onexit
     * will do the right thing when called, including for C++
     * d-tors.
     */
    __onexitbegin = __onexitend = (_PVFV *) EncodePointer((_PVFV *)(-1));

    /*
     * Propogate the _fmode and _commode variables to the DLL
     */
    *_IMP___FMODE = _fmode;
    *_IMP___COMMODE = _commode;

    /*
     * Run the RTC initialization code for this DLL
     */
#ifdef _RTC
    _RTC_Initialize();
#endif  /* _RTC */

    /*
     * Call _setargv(), which will trigger a call to __setargv() if
     * SETARGV.OBJ is linked with the EXE.  If SETARGV.OBJ is not
     * linked with the EXE, a dummy _setargv() will be called.
     */
#ifdef WPRFLAG
    _wsetargv();
#else  /* WPRFLAG */
    _setargv();
#endif  /* WPRFLAG */

    /*
     * If the user has supplied a _matherr routine then set
     * __pusermatherr to point to it.
     */
    if ( !__defaultmatherr )
        __setusermatherr(_matherr);

#ifdef _M_IX86
    _setdefaultprecision();
#endif  /* _M_IX86 */

    /* Enable per-thread locale if user asked for it */
    if(__globallocalestatus == -1)
    {
        _configthreadlocale(-1);
    }

    return 0;
}

/***
*pre_cpp_init(void)
*
*Purpose:
*       The code in mainCRTStartup that was executed after C initializers and
*       before C++ initializers is shifted in this function. Also this funciton
*       is the first thing that is executed in C++ init section.
*
*Entry:
*
*Exit:
*
*******************************************************************************/

static void __cdecl pre_cpp_init(void)
{
#ifdef _RTC
    atexit(_RTC_Terminate);
#endif  /* _RTC */

    /*
     * Get the arguments for the call to main. Note this must be
     * done explicitly, rather than as part of the dll's
     * initialization, to implement optional expansion of wild
     * card chars in filename args
     */

    startinfo.newmode = _newmode;


#ifdef WPRFLAG
    argret = __wgetmainargs(&argc, &argv, &envp,
                            _dowildcard, &startinfo);
#else  /* WPRFLAG */
    argret = __getmainargs(&argc, &argv, &envp,
                           _dowildcard, &startinfo);
#endif  /* WPRFLAG */

#ifndef _SYSCRT
    if (argret < 0)
        _amsg_exit(_RT_SPACEARG);
#endif  /* _SYSCRT */
}

/***
*mainCRTStartup(void)
*wmainCRTStartup(void)
*WinMainCRTStartup(void)
*wWinMainCRTStartup(void)
*
*Purpose:
*       These routines do the C runtime initialization, call the appropriate
*       user entry function, and handle termination cleanup.  For a managed
*       app, they then return the exit code back to the calling routine, which
*       is the managed startup code.  For an unmanaged app, they call exit and
*       never return.
*
*       Function:               User entry called:
*       mainCRTStartup          main
*       wmainCRTStartup         wmain
*       WinMainCRTStartup       WinMain
*       wWinMainCRTStartup      wWinMain
*
*Entry:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -