之前的文章【参考1】,提出了一个问题:为什么 CLIB 下面收到的参数 IN
char
**Argv 实际上是一个 Unicode ?
为了回答这个问题,还要在代码中寻找答案。同样,追踪一下当我们使用 CLIB 的时候,编译过程中程序被添加了什么。分析方法和之前的类似,我们最终得到下面这个结果:
_ModuleEntryPoint:\MdePkg\Library\UefiApplicationEntryPoint\ApplicationEntryPoint.c 入口还是他
框架没变
ProcessLibraryConstructorList (1)
ProcessModuleEntryPointList (2)
ProcessLibraryDestructorList (3)
(1) ProcessLibraryConstructorList:\Build\AppPkg\DEBUG_VS2008\IA32\AppPkg\Applications\ArgTest\ArgTest\DEBUG\AutoGen.c
Status = UefiRuntimeServicesTableLibConstructor (ImageHandle, SystemTable); (1.1) Status = UefiBootServicesTableLibConstructor (ImageHandle, SystemTable);(1.2) Status = UefiLibConstructor (ImageHandle, SystemTable); (1.3) Status = ShellLibConstructor (ImageHandle, SystemTable); (1.4) Status = UefiHiiServicesLibConstructor (ImageHandle, SystemTable); (1.5) Status = __wchar_construct (ImageHandle, SystemTable); (1.6)
(1.1) UefiRuntimeServicesTableLibConstructor :\MdePkg\Library\UefiRuntimeServicesTableLib\UefiRuntimeServicesTableLib.c
(1.2) UefiBootServicesTableLibConstructor :\MdePkg\Library\UefiBootServicesTableLib\UefiBootServicesTableLib.c
(1.3) UefiLibConstructor :\MdePkg\Library\UefiLib\UefiLib.c
(1.4) ShellLibConstructor :\ShellPkg\Library\UefiShellLib\UefiShellLib.c
ShellLibConstructorWorker //加载一些 Shell Protocol
(1.5) UefiHiiServicesLibConstructor :\MdeModulePkg\Library\UefiHiiServicesLib\UefiHiiServicesLib.c
(1.6) __wchar_construct :\StdLib\LibC\Wchar\ConsDecons.c
(2) ProcessModuleEntryPointList :\Build\AppPkg\DEBUG_VS2008\IA32\AppPkg\Applications\ArgTest\ArgTest\DEBUG\AutoGen.c
return ShellCEntryLib (ImageHandle, SystemTable); (2.1)
(2.1) ShellCEntryLib : \ShellPkg\Library\UefiShellCEntryLib\UefiShellCEntryLib.c
ReturnFromMain = ShellAppMain ( EfiShellParametersProtocol->Argc, EfiShellParametersProtocol->Argv );
(2.1.1) ShellAppMain : \StdLib\LibC\Main\Main.c
ExitVal = (INTN)main( (int)Argc, (wchar_t **)Argv);
对照 map 文件可以看到这个main就是我们写的 ArgTest中的Main
0001:000007d0 _ShellGetEnvironmentVariable 00000a50 f UefiShellLib:UefiShellLib.obj
0001:000007eb _ShellIsFile 00000a6b f UefiShellLib:UefiShellLib.obj
0001:00000830 _UefiHiiServicesLibConstructor 00000ab0 f UefiHiiServicesLib:UefiHiiServicesLib.obj
0001:000008a8 _main 00000b28 f ArgTest:ArgTest.obj
0001:00000962 _GetPerformanceCounter 00000be2 f BaseTimerLibNullTemplate:TimerLibNull.obj
0001:00000967 _GetPerformanceCounterProperties 00000be7 f BaseTimerLibNullTemplate:TimerLibNull.obj
(3) ProcessLibraryDestructorList :\Build\AppPkg\DEBUG_VS2008\IA32\AppPkg\Applications\ArgTest\ArgTest\DEBUG\AutoGen.c
Status = __wchar_deconstruct (ImageHandle, SystemTable); (3.1) Status = ShellLibDestructor (ImageHandle, SystemTable); (3.2)
(3.1) __wchar_deconstruct :\StdLib\LibC\Wchar\ConsDecons.c
(3.2) ShellLibDestructor :\ShellPkg\Library\UefiShellLib\UefiShellLib.c
上面的调用关系可以用下面的图来简单总结一下
====================================分割线====================================
我们在运行期确定是下面的代码来取得参数的
// // try to get shell 1.0 interface instead. // Status = SystemTable->BootServices->OpenProtocol(ImageHandle, &gEfiShellInterfaceGuid, (VOID **)&EfiShellInterface, ImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (!EFI_ERROR(Status)) { // // use shell 1.0 interface // ReturnFromMain = ShellAppMain ( EfiShellInterface->Argc, EfiShellInterface->Argv ); } else { ASSERT(FALSE); }
对于这个EfiShellInterface ,我们可以在 《EFI Shell Developer’s Guide》 找到。
因此,可以看到,取出来的Argc就是CHAR16.
参考:
1.http://www.lab-z.com/step-to-uefi-15%EF%BC%89-%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0-again/