为什么需要在 FormatMessage 中转换 lpBuffer (LPTSTR) 参数?

404*_*404 2 c c++ winapi formatmessage

在Windows的FormatMessage()函数中,参数:

  _Out_     LPTSTR lpBuffer
Run Code Online (Sandbox Code Playgroud)

我正在认真思考。按照 Hart 的 Windows 系统编程书籍,我声明一个LPTSTR指针用作lpBuffer(例如LPTSTR errortext;),然后调用该FormatMessage()函数。

传入该参数的正确方法是:(LPTSTR)&errorText

这很好用。但我不明白为什么我需要写(LPTSTR)。我知道这是类型转换,我读到了它,但它对我来说没有意义,因为我没有改变变量类型或任何东西,我将它声明为 anLPTSTR并且我将它的内存地址传递给函数,函数需要 anLPTSTR并且我将其传递给了 an LPTSTR,那么为什么我需要将其(LPTSTR)作为参数的一部分呢lpBuffer

ala*_*ain 5

lpBuffer的参数FormatMessage()记录如下:

指向缓冲区的指针,该缓冲区接收指定格式化消息的空终止字符串。如果 dwFlags 包含 FORMAT_MESSAGE_ALLOCATE_BUFFER,则该函数使用 LocalAlloc 函数分配缓冲区,并将指向缓冲区的指针放置在 lpBuffer 中指定的地址处。

所以有 2 种不同的用法FormatMessage()

1)提供自己的缓冲区

const DWORD bufsize = ....;
TCHAR buf[bufsize];
FormatMessage(.... buf, bufsize, ....); // buf is passed as a TCHAR*
Run Code Online (Sandbox Code Playgroud)

2)FormatMessage为你分配一个缓冲区

const DWORD bufsize = ....;
TCHAR* buf = 0;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | ....,
    .... (LPTSTR)&buf, bufsize, ....); // &buf is a TCHAR** so type-cast needed!
....
LocalFree(buf);
Run Code Online (Sandbox Code Playgroud)

在 #1 中,您必须传递TCHAR缓冲区中第一个地址,该函数只需将其填充到缓冲区即可。

在 #2 中,函数需要告诉您它在哪里分配新缓冲区,因此您必须告诉它将该地址放置在哪里。您必须传递接收地址的指针变量的地址。

简而言之:

  • #1 需要TCHAR*一个现有的缓冲区
  • #2 需要一个TCHAR**接收新缓冲区的

这就是为什么lpBuffer在使用 #2 时必须对参数进行类型转换。

  • @user3733070 是的,在这两种情况下,“buf”只是指向文本的指针。在 1) 中,直接传递指针以使函数能够访问文本,但在 2) 中,函数需要访问指针,因此可以使用“&buf”传递指针的地址。`buf` 是 `TCHAR*`,`&buf` 是 `TCHAR**`。该函数被声明为采用“TCHAR*”,因此“TCHAR**”被强制转换回“TCHAR*”。 (2认同)