最近又在开关于Debug Message的内容,因此研究了一下BASE_LIST。简单的说,有时候你要传递一些长度不定的数据就可以使用这个定义。比如,一个数据块,有时候其中有10个UINTN,有时候其中有2个UINTN (特别注意的是每个单元的大小必须相同)。
具体结构体定义在 Edk2\MdePkg\Include\Base.h,可以看到BASE_LIST 实际上是一个指向 UINTN 的指针。
///
/// Pointer to the start of a variable argument list stored in a memory buffer. Same as UINT8 *.
///
typedef UINTN *BASE_LIST;
此外,经常和 BASE_ARG 结合起来使用,这个宏会返回指针指向的下一个值:
/**
Returns an argument of a specified type from a variable argument list and updates
the pointer to the variable argument list to point to the next argument.
This function returns an argument of the type specified by TYPE from the beginning
of the variable argument list specified by Marker. Marker is then updated to point
to the next argument in the variable argument list. The method for computing the
pointer to the next argument in the argument list is CPU specific following the EFIAPI ABI.
@param Marker The pointer to the beginning of a variable argument list.
@param TYPE The type of argument to retrieve from the beginning
of the variable argument list.
@return An argument of the type specified by TYPE.
**/
#define BASE_ARG(Marker, TYPE) (*(TYPE *) ((Marker += _BASE_INT_SIZE_OF (TYPE)) - _BASE_INT_SIZE_OF (TYPE)))
编写代码验证:
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/ShellCEntryLib.h>
INTN
EFIAPI
ShellAppMain (
IN UINTN Argc,
IN CHAR16 **Argv
)
{
UINTN A[4]={1,2,3,4};
BASE_LIST TestList;
TestList=(BASE_LIST) &A;
for (int i=0;i<4;i++) {
Print(L"%d ",BASE_ARG(TestList,UINTN));
}
Print(L"\n");
return(0);
}
运行结果:
