我在C ++中有一些遗留代码可以做一些我不理解的事情。我在运行Windows XP的计算机上运行Visual C ++ 2008 Express Edition。
代码使用了一些Windows函数:GetAdaptersInfo和GetAdaptersAddressess。我意识到这两个的最后一个参数是指向缓冲区大小的指针,因为它是in_out,所以可以在函数内进行更改。
我的问题是:这些函数是否应该改变缓冲区长度?
在我的代码中,每次调用这些函数时,缓冲区长度变量都被初始化为零,并且在调用函数之后,它仍然是0.
答案 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!
这是一个错误还是我错过了什么?