首页 > 编程语言 >C++如何获取网卡地址(跨平台)

C++如何获取网卡地址(跨平台)

时间:2023-05-10 11:48:09浏览次数:42  
标签:__ int pCur C++ 网卡 跨平台 str outBufLen include

需求:

  获取电脑网卡的硬件地址。就是Linux下运行ifconfig出来的硬件地址。直接上代码:  

windows下运行 ipconfig /all  显示的物理地址。

 

 

头文件:

GetMacAddrFunc.h

#ifndef __DDR_GET_MAC_ADDR_FUNC_H_INCLUDED__
#define __DDR_GET_MAC_ADDR_FUNC_H_INCLUDED__

#include <vector>
#include <string>

namespace DDRGadgets {
    // 获取机器的MAC地址
    std::vector<std::string> GetMacAddr();
}

#endif // __DDR_GET_MAC_ADDR_FUNC_H_INCLUDED__

源码:

windows下要定义宏:_WIN32和_WIN64

linux下要定义宏:__linux__

GetMacAddrFunc.cpp

#include "GetMacAddrFunc.h"

#include <string>
#if defined(_WIN32) || defined(_WIN64)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <iphlpapi.h>
#pragma comment(lib, "iphlpapi.lib")
#elif defined(__linux__)
#include <ifaddrs.h>
#include <netpacket/packet.h>
#endif

namespace DDRGadgets {

    std::vector<std::string> GetMacAddr()
    {
        std::vector<std::string> vec;
        std::string str;
#if defined(_WIN32) || defined(_WIN64)
        ULONG outBufLen = 0;
        DWORD dwRetVal = ::GetAdaptersInfo(0, &outBufLen);
        if (ERROR_BUFFER_OVERFLOW != dwRetVal) {
            return vec;
        }
        outBufLen = ((outBufLen + sizeof(IP_ADAPTER_INFO) - 1) / sizeof(IP_ADAPTER_INFO));
        IP_ADAPTER_INFO *AdapterInfos = new IP_ADAPTER_INFO[outBufLen];
        outBufLen *= sizeof(IP_ADAPTER_INFO);
        dwRetVal = ::GetAdaptersInfo(AdapterInfos, &outBufLen);
        if (NO_ERROR != dwRetVal) {
            return vec;
        }
        outBufLen /= sizeof(IP_ADAPTER_INFO);
        for (int jj = 0; jj < outBufLen; ++jj) {
            str.resize(3 * AdapterInfos[jj].AddressLength - 1);
            char *pCur = &str[0];
            for (int i = 0; i < (int)AdapterInfos[jj].AddressLength; ++i) {
                pCur += snprintf(pCur, 3, "%02x", (int)AdapterInfos[jj].Address[i]);
                if (i + 1 < (int)AdapterInfos[jj].AddressLength) {
                    *(pCur++) = ':';
                }
            }
            vec.push_back(str);
        }
        delete[] AdapterInfos;

#else
        struct ifaddrs *pIfAddr;
        if (-1 == getifaddrs(&pIfAddr)) {
            return vec;
        }
        struct ifaddrs *pIFA = pIfAddr;
        for (; pIFA; pIFA = pIFA->ifa_next) {
            if (!(pIFA->ifa_addr) || AF_PACKET != pIFA->ifa_addr->sa_family) {
                continue;
            }
            auto paddr = (sockaddr_ll*)pIFA->ifa_addr;
            bool bNullAddr = true;
            for (int i = 0; i < (int)paddr->sll_halen; ++i) {
                if (0 != (int)paddr->sll_addr[i]) {
                    bNullAddr = false;
                    break;
                }
            }
            if (bNullAddr) {
                continue;
            }
            str.resize((int)paddr->sll_halen * 3 - 1);
            char *pCur = &str[0];
            for (int i = 0; i < (int)paddr->sll_halen; ++i) {
                pCur += snprintf(pCur, 3, "%02x", (int)paddr->sll_addr[i]);
                if (i + 1 < (int)paddr->sll_halen) {
                    *(pCur++) = ':';
                }
            }
            vec.push_back(str);
        }
        freeifaddrs(pIfAddr);
#endif
        return vec;
    }

}

测试代码:

macTest.cpp

// ... 要包含头文件 ...

void test20230510()
{
    auto vecMacAddr = DDRGadgets::GetMacAddr();
    int i = 0;
    for (auto iii : vecMacAddr)
    {
        i++;
        printf("MacAddr%d:%s\n", i, iii.c_str());
    }
}

int main()
{
    std::cout << "Mac Test ...\n";
    test20230510();
    return 0;
}

结果:

注意编译时要带上 -std=C++11

windows下:

 

标签:__,int,pCur,C++,网卡,跨平台,str,outBufLen,include
From: https://www.cnblogs.com/xcywt/p/17387448.html

相关文章

  • C#调用C++
    一直是在写C#,最近接触到的项目中有C#调用C++接口的逻辑,自己学习了下,写个步骤日志,C#掉用C++的托管代码项目分三个项目:1、底层C++动态库项目,2、中间层的CLR项目,3、上层的C#项目1.底层C++动态库项目,1、新建一个C++动态链接库(Dll)项目,获取新建了其他的项目后在项目属性中将配置类型......
  • C++标准库和模板库的区别和联系?
    C++标准库包含模板库。C++标准库由三组库构成(std::是个名称空间标识符,C++标准库中的函数或者对象都是在命名空间std中定义的):(1)C库:由C标准库扩展而来,强调结构、函数和过程,不支持面向对象技术。(2)C++库:增加了面向对象的库,包含了既有关键功能的类(3)标准模板库(STL):高效的C++程序库。该......
  • Effective Modern C++ 学习笔记
    前言记录下阅读此书的感想与总结,一方面能巩固复习,另一方面也能更好地浓缩本书的精华,方便日后的回看。第五章右值引用、移动语义和完美转发它们带来的好处移动语义使得编译器能使用效率更高的移动操作来替换昂贵的复制操作移动语义使得创建只移对象成为可能,如:std::unique_ptr,t......
  • [C++特性]对std::move和std::forward的理解
    左值、右值、左值引用以及右值引用std::move和std::forward这两个API主要服务于左值引用和右值引用的转化和转发,因此再了解这两个API之前,需要先弄清楚这几个概念。左值:一般指的是在内存中有对应的存储单元的值,最常见的就是程序中创建的变量右值:和左值相反,一般指的是没有对应存......
  • 每日打卡c++中vector容器使用
    首先头文件#include<vector>for_each一种算法需要头文件#include<algorithm>标准算法头文件vector<int>::iterator迭代器,可以当指针用。基本格式vector<数据类型>名称;数据类型可以是类。例子#include<iostream>#include<vector>#include<algorithm>usingnamespacestd;cla......
  • c++打卡第二十一天
    一、爱因斯坦的数学题1、问题描述2、设计思路。①、输入N,从1到n遍历。②、寻找满足上述条件的数,得到符合条件的个数加一并打印出这个数。3、流程图4、代码实现#include<iostream>usingnamespacestd;intmain(){intN;intflag=1;intcount;whi......
  • 现代 C++:Lambda 表达式
    Lambda表达式(LambdaExpression)是C++11引入的一个“语法糖”,可以方便快捷地创建一个“函数对象”。从C++11开始,C++有三种方式可以创建/传递一个可以被调用的对象:函数指针仿函数(Functor)Lambda表达式函数指针函数指针是从C语言老祖宗继承下来的东西,比较原始,功能也比......
  • C++ Lambda表达式的完整介绍
    c++在c++11标准中引入了lambda表达式,一般用于定义匿名函数,使得代码更加灵活简洁。lambda表达式与普通函数类似,也有参数列表、返回值类型和函数体,只是它的定义方式更简洁,并且可以在函数内部定义。什么是Lambda表达式最常见的lambda的表达式写法如下autoplus=[](intv1,int......
  • C++11 lambda表达式精讲
    lambda表达式是C++11最重要也最常用的一个特性之一,C#3.5和Java8中就引入了lambda表达式。 lambda来源于函数式编程的概念,也是现代编程语言的一个特点。C++11这次终于把lambda加进来了。 lambda表达式有如下优点:声明式编程风格:就地匿名定义目标函数或函数对......
  • 1009 说反话(C++)
    一、问题描述:给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。输入格式:测试输入包含一个测试用例,在一行内给出总长度不超过80的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用1个空格分开,输入保证句子末尾没有......