GetAdaptersInfo和GetAdaptersAddressess BufferLength Param

时间:2009-07-01 17:25:05

标签: c++ windows visual-c++ windows-xp

我在C ++中有一些遗留代码可以做一些我不理解的事情。我在运行Windows XP的计算机上运行Visual C ++ 2008 Express Edition。

代码使用了一些Windows函数:GetAdaptersInfo和GetAdaptersAddressess。我意识到这两个的最后一个参数是指向缓冲区大小的指针,因为它是in_out,所以可以在函数内进行更改。

我的问题是:这些函数是否应该改变缓冲区长度?

在我的代码中,每次调用这些函数时,缓冲区长度变量都被初始化为零,并且在调用函数之后,它仍然是0.

3 个答案:

答案 0 :(得分:6)

当然,@RichieHindle's answer中的示例代码包含竞争条件....如果Windows想要返回的结构的大小在第一次调用GetAdaptersInfo()之后但在第二次调用GetAdaptersInfo之前增长( ),对GetAdaptersInfo()的第二次调用也会因ERROR_BUFFER_OVERFLOW而失败,并且您的函数将无法正常工作。

是的,这确实发生在现实生活中 - 我曾经遇到过这种情况。如果您希望代码可靠,则需要在循环中调用GetAdaptersInfo(),根据需要多次增加缓冲区的大小,直到调用成功为止。

构建API的方法必须少于错误......不幸的是,微软还没有找到它。 :^ P

答案 1 :(得分:3)

您的代码需要看起来像这样:

// First get the desired size.
unsigned long outBufLen = 0;
DWORD dwResult = GetAdaptersInfo(NULL, &outBufLen);
if (dwResult == ERROR_BUFFER_OVERFLOW)  // This is what we're expecting
{
    // Now allocate a structure of the requried size.
    PIP_ADAPTER_INFO pIpAdapterInfo = (PIP_ADAPTER_INFO) malloc(outBufLen);
    dwResult = GetAdaptersInfo(pIpAdapterInfo, &outBufLen);
    if (dwResult == ERROR_SUCCESS)
    {
        // Yay!

编辑:另请参阅Jeremy Friesner对此代码不足的原因的回答。

答案 2 :(得分:1)

确实,使用Visual Studio 6,我曾经通过以下方式获得适配器的数量:

DWORD drc = GetAdaptersInfo(NULL, &(Buflen = 0L));

if (drc == ERROR_BUFFER_OVERFLOW)
  n = Buflen / sizeof(IP_ADAPTER_INFO);

没关系,例如对于2个适配器,Buflen设置为1280,sizeof(IP_ADAPTER_INFO)为640。

现在我正在使用Visual C ++ 2008 Express并且我的结果被截断,因为该函数仍将Buflen设置为1280,但sizeof(IP_ADAPTER_INFO)的值现在为648!

这是一个错误还是我错过了什么?