More data is available
函数出现GetComputerNameEx
错误,但不知道如何修复它。
这是我的代码:
int wmain()
{
COMPUTER_NAME_FORMAT nameType = ComputerNameDnsFullyQualified;
WCHAR computerName[MAX_COMPUTERNAME_LENGTH + 1];
DWORD size = ARRAYSIZE(computerName);
BOOL pcName = GetComputerNameEx(nameType, computerName, &size);
DWORD error = GetLastError();
if (pcName != 0)
{
wprintf("Computer name: %s\n", computerName);
}
else
{
wprintf(L"Error getting the name. Code: %li\n", error);
}
return 0;
}
不知道如何将size
变量设置为输出,以便我可以正确声明computerName
数组。
答案 0 :(得分:5)
你必须两次调用该函数;一次使用空指针获取所需大小,并再次使用(至少)指定大小的缓冲区。正如文档所说:
要确保此缓冲区足够大,请将此参数设置为NULL 并使用lpnSize参数中返回的所需缓冲区大小。
这是Win32功能的常见模式。是的,它确实会导致可能的竞争条件,但这就是它的运作方式。
示例强>
DWORD dwSize = 0;
if (GetComputerNameEx(nameType, nullptr, &dwSize))
{
WCHAR* computerName;
computerName = (WCHAR*)malloc(dwSize * sizeof(WCHAR));
if (GetComputerNameEx(nameType, computerName, &dwSize))
{
// use the name
}
free(computerName); // don't forget to free
}
答案 1 :(得分:3)
根据GetComputerNameEx()
文档:
lpBuffer [out]
指向接收计算机名称或群集虚拟服务器名称的缓冲区的指针。名称的长度可能大于
MAX_COMPUTERNAME_LENGTH
个字符,因为DNS允许更长的名称。要确保此缓冲区足够大,请将此参数设置为NULL
并使用lpnSize
参数中返回的所需缓冲区大小。lpnSize [in,out]
输入时,在TCHAR
s中指定缓冲区的大小。在输出时,接收复制到目标缓冲区的TCHAR
个数,不包括终止空字符。如果缓冲区太小,则函数失败,
GetLastError
返回ERROR_MORE_DATA
。此参数接收所需缓冲区的大小,包括终止空字符。如果
lpBuffer
为NULL,则此参数必须为零。
例如:
int wmain()
{
COMPUTER_NAME_FORMAT nameType = ComputerNameDnsFullyQualified;
WCHAR *computerName = NULL, *computerNameNew;
DWORD size = 0;
BOOL pcName;
DWORD error;
do
{
pcName = GetComputerNameExW(nameType, computerName, &size);
if (pcName) break;
error = GetLastError();
if (error != ERROR_MORE_DATA) break;
computerNameNew = (WCHAR*) realloc(computerName, sizeof(WCHAR) * size);
if (!computerNameNew) {
error = ERROR_OUTOFMEMORY;
break;
}
computerName = computerNameNew;
}
while (1);
if (pcName)
{
wprintf("Computer name: %s\n", computerName);
}
else
{
wprintf(L"Error getting the name. Code: %ul\n", error);
}
free(computerName);
return 0;
}
答案 2 :(得分:1)
该错误意味着GetComputerNameEx
函数需要更大的缓冲区来存储返回的字符串。
为了避免Jonathan Potter的回答中引用的竞争条件,你可以这样做:
LONG error = ERROR_MORE_DATA;
WCHAR* buffer = NULL;
DWORD bufferLength = /* Some initial reasonable length for the string buffer */;
while (error == ERROR_MORE_DATA) {
// Create a buffer with bufferLength size (measured in WCHARs)
buffer = realloc(buffer, bufferLength * sizeof(WCHAR));
if (GetComputerNameEx(nameType, buffer, &bufferLength)) {
error = ERROR_SUCCESS;
} else {
error = GetLastError();
}
}
if (error != ERROR_SUCCESS) {
// Some error occurred
...
}
// Use buffer containing computer name
// Don't forget to free(buffer)