Step to UEFI (269)PRINT 前缀的研究

众所周知,在编写 UEFI Shell Application的时候,使用 PRINT(L”My String”) 可以非常容易的在屏幕上输出字符串。偶然机会看到了关于前缀“L”的介绍【参考1】。它能够决定后面的字符串的编码方式。简单介绍如下:

  • Ordinary character literals of type char, for example 'a'
  • UTF-8 character literals of type char (char8_t in C++20), for example u8'a'
  • Wide-character literals of type wchar_t, for example L'a'
  • UTF-16 character literals of type char16_t, for example u'a'
  • UTF-32 character literals of type char32_t, for example U'a'

编写一个简单的代码进行测试,使用上述四种前缀来定义字符串,然后在代码中输出字符串对应的内存数值:

#include  <Uefi.h>
#include  <Library/UefiLib.h>
#include  <Library/ShellCEntryLib.h>

CHAR8  *s1="www.lab-z.com";
CHAR16 *s2=L"www.lab-z.com";
CHAR16 *s3=u"www.lab-z.com";
CHAR16 *s4=(CHAR16 *)U"www.lab-z.com";
	
UINTN OUTPUTCHAR(CHAR8 *p,UINTN Length) {
	UINTN i=0;
	for (;i<Length;i++) {
		Print(L"%02X  ",p[i]);
	}
	return 0;
}

INTN
EFIAPI
ShellAppMain (
  IN UINTN Argc,
  IN CHAR16 **Argv
  )
{
  Print(L"S1:[");OUTPUTCHAR((CHAR8*)s1,14);Print(L"]\n");
  Print(L"S2:[");OUTPUTCHAR((CHAR8*)s2,14*2);Print(L"]\n");
  Print(L"S3:[");OUTPUTCHAR((CHAR8*)s3,14*2);Print(L"]\n");
  Print(L"S4:[");OUTPUTCHAR((CHAR8*)s4,14*4);Print(L"]\n");

  return(0);
}

可以看出:

  1. 不加前缀,直接定义为 ASCII对应的数值;
  2. L 前缀,会使用 UTF-16 编码;
  3. u(小写)前缀,和L 一样,都是 UTF-16 编码;
  4. U(大写)前缀,将会使用UTF-32编码。

我们经常在GCC 编写的 UEFI 代码中看到使用u的定义方式,看起来这个应该是C语言标准的写法,具体可以在【参考2】和【参考3】看到。

参考:

  1. https://learn.microsoft.com/en-us/cpp/cpp/string-and-character-literals-cpp?view=msvc-170
  2. https://learn.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance?view=msvc-170
  3. https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1041r4.html

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注