从GetAdaptersAddresses返回ERROR_INSUFFICIENT_BUFFER

时间:2012-09-05 10:12:13

标签: c++ winapi

使用以下代码,或多或少地从MSDN example of GetAdaptersAddresses复制粘贴,我得到返回值122,这意味着ERROR_INSUFFICIENT_BUFFER(根据this system error code list)。

ULONG outBufLen = 150000;   // Tried for different (large) values here...
PIP_ADAPTER_ADDRESSES pAddresses = (IP_ADAPTER_ADDRESSES *) malloc(outBufLen);
DWORD dwRetVal = GetAdaptersAddresses(AF_INET, 0, NULL, pAddresses, &outBufLen);
// ....
free(pAddresses);

GetAdaptersAddresses的文档未将ERROR_INSUFFICIENT_BUFFER列为预期返回值之一。 (它列出了ERROR_BUFFER_OVERFLOW,它应该将outBufLen调整为所需的值,但保持不变)。

使用GetAdaptersInfo会导致相同的症状。

在我的开发计算机上,但在一个虚拟和一个真正干净的Windows 7 x86 SP1安装上没有发生此错误(添加了VC ++可再发行组件)。

作为一名c ++新手,我做错了吗?什么可能导致此错误以及如何解决它? =)

4 个答案:

答案 0 :(得分:4)

首先,你可以 - 像其他人建议的那样 - 做两次调用,找出所需的缓冲区大小,然后自己进行查询。特别是如果您看到错误,那么您的第一次尝试就是询问API预期的大小。

其次,你需要知道这个API在消耗大量内存的32位进程中并不十分安全,因此缓冲区可以扩展到更高的2GB地址空间。 API可能会以一种奇怪的方式开始,无论是由于它自己的错误还是底层的错误。在MS Connect上查看详细信息:GetAdaptersAddresses API incorrectly returns no adapters for a process with high memory consumption

错误代码不是“预期返回值之一”这一事实告诉了错误来自底层的版本,而这个API只是在内部失败时将其传递出去。作为线索,在系统上禁用某些网络适配器后,您可能会摆脱错误。

答案 1 :(得分:1)

Visual Studio将一个名为“IPHLPAPI.dll”的库与我的项目一起部署,从而导致了问题。删除此文件解决了它。

为什么会出现这种情况需要进一步研究=)

答案 2 :(得分:0)

首先,缓冲区是一块内存。

如此不足可能意味着你没有给它足够的记忆。我们可能是您无法访问的内存块。也许地址甚至不存在。

看看这个:

ERROR_INSUFFICIENT_BUFFER
    122 (0x7A)

    The data area passed to a system call is too small.

这听起来很像缓冲区没有足够的分配内存。或类似的。

也许是

outBufLen 

必须是特定长度,可能是内存块的大小。因为有时它不会检查“名称”,但会尝试比较每个变量的大小。这个想法来自高级着色器语言。

所以我会尝试在以下方面看一点:

ULONG outBufLen = 150000;   // Tried for different (large) values here...
PIP_ADAPTER_ADDRESSES pAddresses = (IP_ADAPTER_ADDRESSES *) malloc(outBufLen);
祝你好运!

答案 3 :(得分:0)

要知道所需的确切缓冲区大小,您只需将NULL传递给pAddresses,并将大小设置为所需的大小。您可能需要稍微重写代码才能使其正常工作;

DWORD rv, size = 0;
PIP_ADAPTER_ADDRESSES adapter_addresses;

rv = GetAdaptersAddresses(AF_INET, 0, NULL, NULL, &size);
if (rv != ERROR_BUFFER_OVERFLOW)
    return false; // ERROR

adapter_addresses = (PIP_ADAPTER_ADDRESSES)malloc(size);

rv = GetAdaptersAddresses(AF_INET, 0, NULL, adapter_addresses, &size);
if (rv != ERROR_SUCCESS) {
    free(adapter_addresses);
    return false; // ERROR
}