GetAdaptersInfo 返回 ERROR_BUFFER_OVERFLOW 表示缓冲区不足,需先传 NULL 和指针 size 获取所需大小,再分配内存并重试;提取 MAC 时须验证 AddressLength == 6 且 Type == MIB_IF_TYPE_ETHERNET;该函数因仅支持 IPv4、不兼容新接口,自 Windows XP 起被 GetAdaptersAddresses 取代。

GetAdaptersInfo 返回 ERROR_BUFFER_OVERFLOW 怎么办
调用 GetAdaptersInfo 时返回 ERROR_BUFFER_OVERFLOW 是最常见卡点,不是失败,而是缓冲区太小——系统根本没给你填数据的机会。
正确做法是先传入 NULL 和 size = 0 调用一次,让系统把所需缓冲区大小写进 size;再 malloc 对应内存,二次调用。两次调用之间不能有网络配置变更(如插拔网线),否则 size 可能失效。
- 第一次调用必须检查返回值是否为
ERROR_BUFFER_OVERFLOW,不能只看是否非零 - 分配内存时用
new BYTE[size]或malloc(size),别用栈数组(容易栈溢出) - 第二次调用前确保
size是上一次调用后更新的值,且指针非空
如何从 IP_ADAPTER_INFO 结构里安全提取 MAC 地址
IP_ADAPTER_INFO 的 Address 字段是 8 字节数组,但有效 MAC 只有前 6 字节;AddressLength 字段告诉你当前适配器地址长度,不一定是 6 —— 某些虚拟网卡或隧道接口可能填 0 或 8,直接硬取前 6 字节会越界或错读。
必须同时满足两个条件才认为是有效以太网 MAC:
pAdapter->AddressLength == 6-
pAdapter->Type == MIB_IF_TYPE_ETHERNET(不是MIB_IF_TYPE_LOOPBACK或MIB_IF_TYPE_TUNNEL)
示例判断逻辑:
if (pAdapter->AddressLength == 6 && pAdapter->Type == MIB_IF_TYPE_ETHERNET) {
for (int i = 0; i Address[i]);
if (i <h3>为什么 GetAdaptersInfo 在 Windows XP 后逐渐被弃用</h3><p><code>GetAdaptersInfo</code> 无法返回 IPv6 配置、不支持新式网络接口(如 WSL2 虚拟网卡)、对绑定多个 IP 的适配器只返回第一个 IP,且整个 API 是基于 IPv4 的旧架构。Windows Vista 起官方推荐改用 <code>GetAdaptersAddresses</code>。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2823" title="C++14"><img
src="https://img.php.cn/upload/manual/001/431/639/6ac8b33c327c4749.png" alt="C++14" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="overflowclass">C++14</a>
<p class="overflowclass">C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。</p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div><p>关键差异:</p>
-
GetAdaptersAddresses返回链表结构IP_ADAPTER_ADDRESSES,支持 IPv4/IPv6 混合地址族 - MAC 地址字段名改为
PhysicalAddress,长度仍存于PhysicalAddressLength - 需显式指定
AF_INET或AF_UNSPEC,传AF_UNSPEC才能拿到物理地址(即使你只关心 MAC) - 返回值为
NO_ERROR表示成功,错误码不再是 Win32 错误码而是WSA*系列(需用WSAGetLastError()获取)
跨平台获取 MAC 的现实选择
Windows 上用 GetAdaptersAddresses 已足够稳定;Linux/macOS 则必须走 getifaddrs() + 过滤 AF_PACKET 或 AF_LINK 类型接口。没有真正“一套代码通吃”的方案。
如果项目已用 Boost 或 Qt:
- Boost.Asio 提供
network_interface::hardware_address()(v1.70+),封装了各平台细节 - Qt 5.10+ 的
QNetworkInterface::hardwareAddress()也做了兼容处理,但注意它返回的是字符串,不是原始字节数组
自己手写跨平台时,最容易忽略的是:Linux 下部分容器或 network namespace 中的接口可能没有 AF_PACKET 地址,需 fallback 到读 /sys/class/net/*/address 文件——而该路径在 chroot 或无权限容器中可能不可读。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










