gpt4 book ai didi

winapi - 调用返回 ERROR_MORE_DATA 或 ERROR_INSUFFICIENT_BUFFER 的 Win32 API 函数的模式?

转载 作者:行者123 更新时间:2023-12-03 07:49:46 26 4
gpt4 key购买 nike

Win32 SDK 中返回可变大小数据的函数通常允许您传递零大小的缓冲区,然后它们会告诉您需要多少空间。它们往往看起来像以下之一(简化):

LSTATUS RegQueryValueExA (HKEY hKey, LPCSTR lpValueName,
LPDWORD lpReserved, LPDWORD lpType,
LPBYTE lpData, LPDWORD lpcbData);

天真的尝试调用它可能看起来像这样:

DWORD dwType;
DWORD cbData = 0;
LSTATUS status = RegQueryValueEx(hKey, "InstallFolder",
NULL, &dwType,
NULL, &cbData);

BYTE *pData = (BYTE *)malloc(cb);
status = RegQueryValueEx(hKey, "InstallFolder",
NULL, &dwType,
pData, &cbData);

// Do something with pData

其他函数如下所示:

BOOL SetupDiGetClassDescriptionA(CONST GUID *ClassGuid,
PSTR ClassDescription,
DWORD ClassDescriptionSize,
PDWORD RequiredSize);

我的问题:是否有任何模式/模板可以可靠地处理此类功能?例如,如果内存实际上耗尽,或者两次调用之间的大小发生变化?

最佳答案

我不想在第一次尝试时发送 NULL。相反,我传递一个本地定义的缓冲区,其大小足以满足大多数情况。在本地声明,分配上不会浪费时间,唯一的开销是耗尽堆栈的机会(这种情况很小)。即使您传递的实际缓冲区不足,也会返回所需的大小,但前提是在这种情况下您必须从堆中分配缓冲区。这样,您最终肯定会发送一个足够大的缓冲区,并且在大多数情况下,您最终只会调用该函数一次,并且没有动态分配。

例如(未选中):

DWORD dwType;
DWORD cbData = SOME_SIZE;
BYTE *pData, pStackBuffer[SOME_SIZE];
bool bFreeData = false;

pData = pStackBuffer;
LSTATUS status = RegQueryValueEx(hKey, "InstallFolder", NULL, &dwType,
pData, &cbData);
if (status == ERROR_MORE_DATA)
{
pData = (BYTE*)malloc(cbData);
bFreeData = true;
status = RegQueryValueEx(hKey, "InstallFolder", NULL, &dwType,
pData, &cbData);
}

// do the stuff...

if (bFreeData)
free(pData);

关于winapi - 调用返回 ERROR_MORE_DATA 或 ERROR_INSUFFICIENT_BUFFER 的 Win32 API 函数的模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1102806/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com