GetAdaptersInfo和GetAdaptersAddressess BufferLength参数

我在C ++中有一些遗留代码,这些代码有一些我不明白的地方。 我在运行Windows XP的机器上运行Visual C ++ 2008 Express Edition。

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

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

在我的代码中,每次调用这些函数时,缓冲区长度variables都被初始化为0,调用该函数之后,它仍然是0。

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

// 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! 

编辑:另请参阅杰里米弗里斯纳的答案,为什么这个代码是不够的。

当然, @ RichieHindle的答案中的示例代码包含竞争条件….如果结构Windows想要返回的大小在第一次调用GetAdaptersInfo()之后但在第二次调用GetAdaptersInfo()之前增长,则第二次调用GetAdaptersInfo()将会失败,同时ERROR_BUFFER_OVERFLOW也会失败,你的函数将无法工作。

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

构建一个API必须有一个不太容易出错的方法……不幸的是,微软还没有找到它。 :^ P

的确,使用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!

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