如何使用C++在Windows中获取MAC地址?

18

我需要一些关于MAC地址的帮助。我需要使用C++编写代码来获取它,所以能否有人帮助我?我已经尝试了很多无用的代码。如果存在任何特定的方法或库,我应该学习如何查找MAC地址,我会非常高兴如果有人能够给我一个链接或者其他更多的信息。


4
这是一个特定于平台的问题,与(标准)C++无关。因此,请告诉我们您正在尝试获取哪个操作系统的信息。 - Christian.K
MAC地址是哪个媒体访问控制器的?可能有很多个。 - user405725
如果在Windows系统中,这是一个重复的问题:https://dev59.com/CnRA5IYBdhLWcg3wyRN7 - Prof. Falken
操作系统是Windows(所有版本)。将来我也需要为Linux做,但那是在遥远的未来:P - guiarrd
@Prof.Falken:不是重复问题。另一个问题非常特定于大多数代码不应尝试处理的场景。 - Joshua
@Joshua,你可能是对的。 - Prof. Falken
2个回答

33

我明白了!我和一个来自工作的男生使用以下代码解决了这个问题:

#include <stdio.h>
#include <Windows.h>
#include <Iphlpapi.h>
#include <Assert.h>
#pragma comment(lib, "iphlpapi.lib")

char* getMAC();

int main(){ 
  char* pMac = getMAC();
  system("pause");
  free(pMac);
}
char* getMAC() {
  PIP_ADAPTER_INFO AdapterInfo;
  DWORD dwBufLen = sizeof(IP_ADAPTER_INFO);
  char *mac_addr = (char*)malloc(18);

  AdapterInfo = (IP_ADAPTER_INFO *) malloc(sizeof(IP_ADAPTER_INFO));
  if (AdapterInfo == NULL) {
    printf("Error allocating memory needed to call GetAdaptersinfo\n");
    free(mac_addr);
    return NULL; // it is safe to call free(NULL)
  }

  // Make an initial call to GetAdaptersInfo to get the necessary size into the dwBufLen variable
  if (GetAdaptersInfo(AdapterInfo, &dwBufLen) == ERROR_BUFFER_OVERFLOW) {
    free(AdapterInfo);
    AdapterInfo = (IP_ADAPTER_INFO *) malloc(dwBufLen);
    if (AdapterInfo == NULL) {
      printf("Error allocating memory needed to call GetAdaptersinfo\n");
      free(mac_addr);
      return NULL;
    }
  }

  if (GetAdaptersInfo(AdapterInfo, &dwBufLen) == NO_ERROR) {
    // Contains pointer to current adapter info
    PIP_ADAPTER_INFO pAdapterInfo = AdapterInfo;
    do {
      // technically should look at pAdapterInfo->AddressLength
      //   and not assume it is 6.
      sprintf(mac_addr, "%02X:%02X:%02X:%02X:%02X:%02X",
        pAdapterInfo->Address[0], pAdapterInfo->Address[1],
        pAdapterInfo->Address[2], pAdapterInfo->Address[3],
        pAdapterInfo->Address[4], pAdapterInfo->Address[5]);
      printf("Address: %s, mac: %s\n", pAdapterInfo->IpAddressList.IpAddress.String, mac_addr);
      // print them all, return the last one.
      // return mac_addr;

      printf("\n");
      pAdapterInfo = pAdapterInfo->Next;        
    } while(pAdapterInfo);                        
  }
  free(AdapterInfo);
  return mac_addr; // caller must free.
}

http://msdn.microsoft.com/en-us/library/windows/desktop/aa365917(v=vs.85).aspx - dlchambers
我在这段代码中发现了内存泄漏问题:如果 return mac_addr; 发生,那么 free(AdapterInfo); 就不会发生。 另一个问题是,如果 return mac_addr; 没有发生,函数就不会返回任何内容。 但基本思路似乎是正确的。 - Tsar Ioann
1
您可以使用以下代码(替换sprintf)以避免在VS 2015中出现编译错误sprintf_s(mac_addr, 6 * sizeof(pAdapterInfo->Address[1]), "%02X:%02X:%02X:%02X:%02X:%02X", pAdapterInfo->Address[0], pAdapterInfo->Address[1], pAdapterInfo->Address[2], pAdapterInfo->Address[3], pAdapterInfo->Address[4], pAdapterInfo->Address[5]); - qqqqq
1
除非您仍然支持Windows 2000,否则您应该使用GetAdaptersAddresses https://msdn.microsoft.com/en-us/library/windows/desktop/aa365915(v=vs.85).aspx - Joshua
1
而且 mac_addr = (char*)malloc(17); 应该改为 mac_addr = (char*)malloc(18); 这样就有空间来终止字符串。 - Jesse Chisholm
刚刚编辑了代码,使其格式更好,并解决了提到的一些内存问题。 - Jesse Chisholm

4
C++没有内置的“MAC地址”概念,这不是C++代码运行所必须的。因此,它是平台特定的。您必须告诉我们您要为哪个平台进行此操作,并阅读与该平台相匹配的文档。
如果您想以可移植的方式执行此操作,应查找适合所有所需平台的库。
此外,请注意计算机可以拥有任意数量的网络适配器,因此不存在仅有一个MAC地址的要求。

感谢您的回答,unwind。我正在使用Windows的Dev C++。我尝试使用像这样的代码:https://dev59.com/L3VC5IYBdhLWcg3wpjB8?rq=1 - guiarrd
“在Windows中”是一个很好的提示。 - Sam Ginrich

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接