• SDL2使用VS C++应用入门及入口点函数


     

    自上篇文章所述在VS C++生成SDL2库文件,编写简单Hello World程序验证库文件。

     

    1、使用Visual Studio 2019 创建一个终端控制台程序。

    点击“文件—新建—项目”,选择“控制台应用”,输入源代码:

     test.cpp:

     1 #include <iostream>
     2 #include <SDL.h>
     3 
     4 /*
     5  * Lesson 0: Test to make sure SDL is setup properly
     6  */
     7 int main(int, char**) {
     8     if (SDL_Init(SDL_INIT_VIDEO) != 0) {
     9         std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
    10         return 1;
    11     }
    12     std::cout << "SDL_Init OK!!!" << std::endl;
    13     SDL_Quit();
    14 
    15     return 0;
    16 }
    17 
    18 /*
    19 ${SDL2_ROOT}include
    20 ${SDL2_ROOT}VisualCWin32Debug
    21 ${SDL2_ROOT}VisualCWin32Release
    22 SDL2.lib
    23 SDL2main.lib
    24 */

    2、设置库文件目录、依赖项目录、依赖项文件名。

    点击菜单“项目“--->"属性”,在“配置”栏中的“所有配置”适合debug和release都相同的设置,不相同设置单独选择”debug”或”release”配置。上述代码中的${SDL2_ROOT} 替换为你本机实际目录。

    • “配置”:“所有配置”--->“C/C++”--->“常规”--->“附加包含目录” :${SDL2_ROOT}include
    • “配置”:“所有配置”--->“”链接器“--->”输入“--->”附加依赖项“: SDL2.lib、SDL2main.lib
    • “配置”:”Debug”--->“”链接器“--->”常规”--->”附加库目录“: ${SDL2_ROOT}VisualCWin32Debug
    • “配置”:”Release”--->“”链接器“--->”常规”--->”附加库目录“: ${SDL2_ROOT}VisualCWin32Release
    • 拷贝对应debug/release版本的SDL2.dll到对应EXE输出目录。

    执行程序输出结果,如图:

         

    3、补充说明:SDL2入口点函数(入口点符号)。

         

      Test.cpp::main() 中"main"已在头文件SDL_main.h中定义为宏,跟踪宏生效的依赖关系如下 :

        main ---> SDL_main.h::109 ---> SDL_main.h::40 SDL_MAIN_AVAILABLE ---> SDL_main.h::40 __WIN32__ ---> SDL_platform.h::153 __WINDOWS__ ---> SDL_platform.h::149 WINAPI_FAMILY_WINRT ---> SDL_platform.h:: 139 ---> (…) 

      Test.cpp 中"main"最终只会有两种结果,而此示例代码经过预处理后进行编译前函数名实际为:SDL_main 。

     

        条件==true ---> SDL_main()

        条件==false ---> main()

     

       Test.cpp::main()不是程序的入口点函数,这是因WINDOWS平台C++程序对真实第一个入口点函数有定义,微软官方文档说明链接如下:

    https://docs.microsoft.com/zh-cn/cpp/build/reference/entry-entry-point-symbol?view=vs-2019

      由此可见,可分三种情况有三类真正的程序第一个入口函数,再经过固定流程调用指定函数。通过调试本示例分析,得到调用Test.cpp::main() 的函数在SDL_windows_main.c文件,而SDL_windows_main.c::19 执行undef main。

     

     

     SDL_windows_main.c源代码文件如下:

     1 /* Pop up an out of memory message, returns to Windows */
     2 static BOOL
     3 OutOfMemory(void)
     4 {
     5     SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Out of memory - aborting", NULL);
     6     return FALSE;
     7 }
     8 
     9 #if defined(_MSC_VER)
    10 /* The VC++ compiler needs main/wmain defined */
    11 # define console_ansi_main main
    12 # if UNICODE
    13 #  define console_wmain wmain
    14 # endif
    15 #endif
    16 
    17 /* Gets the arguments with GetCommandLine, converts them to argc and argv
    18    and calls SDL_main */
    19 static int
    20 main_getcmdline(void)
    21 {
    22     LPWSTR *argvw;
    23     char **argv;
    24     int i, argc, result;
    25 
    26     argvw = CommandLineToArgvW(GetCommandLineW(), &argc);
    27     if (argvw == NULL) {
    28         return OutOfMemory();
    29     }
    30 
    31     /* Parse it into argv and argc */
    32     argv = (char **)SDL_calloc(argc + 1, sizeof(*argv));
    33     if (!argv) {
    34         return OutOfMemory();
    35     }
    36     for (i = 0; i < argc; ++i) {
    37         argv[i] = WIN_WStringToUTF8(argvw[i]);
    38         if (!argv[i]) {
    39             return OutOfMemory();
    40         }
    41     }
    42     argv[i] = NULL;
    43     LocalFree(argvw);
    44 
    45     SDL_SetMainReady();
    46 
    47     /* Run the application main() code */
    48     result = SDL_main(argc, argv);
    49 
    50     /* Free argv, to avoid memory leak */
    51     for (i = 0; i < argc; ++i) {
    52         SDL_free(argv[i]);
    53     }
    54     SDL_free(argv);
    55 
    56     return result;
    57 }
    58 
    59 /* This is where execution begins [console apps, ansi] */
    60 int
    61 console_ansi_main(int argc, char *argv[])
    62 {
    63     return main_getcmdline();
    64 }
    65 
    66 
    67 #if UNICODE
    68 /* This is where execution begins [console apps, unicode] */
    69 int
    70 console_wmain(int argc, wchar_t *wargv[], wchar_t *wenvp)
    71 {
    72     return main_getcmdline();
    73 }
    74 #endif
    75 
    76 /* This is where execution begins [windowed apps] */
    77 int WINAPI
    78 WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
    79 {
    80     return main_getcmdline();
    81 }
    82 
    83 #endif /* __WIN32__ */
    84 
    85 /* vi: set ts=4 sw=4 expandtab: */

     SDL_windows_main.c源代码经过预处理后,如下:

     1 static BOOL
     2 OutOfMemory(void)
     3 {
     4     SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Out of memory - aborting", ((void *)0));
     5     return 0;
     6 }
     7 
     8 static int
     9 main_getcmdline(void)
    10 {
    11     LPWSTR *argvw;
    12     char **argv;
    13     int i, argc, result;
    14     argvw = CommandLineToArgvW(GetCommandLineW(), &argc);
    15     if (argvw == ((void *)0)) {
    16         return OutOfMemory();
    17     }
    18     argv = (char **)SDL_calloc(argc + 1, sizeof(*argv));
    19     if (!argv) {
    20         return OutOfMemory();
    21     }
    22     for (i = 0; i < argc; ++i) {
    23         argv[i] = SDL_iconv_string("UTF-8", "UTF-16LE", (char *)(argvw[i]), (SDL_wcslen(argvw[i])+1)*sizeof(WCHAR));
    24         if (!argv[i]) {
    25             return OutOfMemory();
    26         }
    27     }
    28     argv[i] = ((void *)0);
    29     LocalFree(argvw);
    30     SDL_SetMainReady();
    31     result = SDL_main(argc, argv);
    32     for (i = 0; i < argc; ++i) {
    33         SDL_free(argv[i]);
    34     }
    35     SDL_free(argv);
    36     return result;
    37 }
    38 int
    39 main(int argc, char *argv[])
    40 {
    41     return main_getcmdline();
    42 }
    43 int
    44 wmain(int argc, wchar_t *wargv[], wchar_t *wenvp)
    45 {
    46     return main_getcmdline();
    47 }
    48 
    49 int __stdcall
    50 WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
    51 {
    52     return main_getcmdline();
    53 }

      经过以上分析后,大家有进一步理解了,本示例代码是在WINDOWS平台下创建为控制台程序,程序是怎样从入口点函数调用到应用层的Test.cpp::main()函数?

     

  • 相关阅读:
    Python 中特殊变量/方法命名规则说明(特别是私有变量)及使用实例
    博客(文本)编辑工具Markdown使用初体验
    Vue2.0关于生命周期和钩子函数
    Vue2.0中的路由配置
    Vue项目中引入外部文件(css、js、less)
    利用vue-cli创建Vue项目
    vue+webpack构建项目
    VueJs2.0建议学习路线
    Python基础 :正则表达式
    Python框架 :WEB框架
  • 原文地址:https://www.cnblogs.com/bluebeecoder/p/13744463.html
Copyright © 2020-2023  润新知