2023.10.25 学习笔记

一. C++获取本机MAC地址

1.首先 什么是MAC地址?

Mac地址(英语:Media Access Control Address),直译为媒体存取控制位址,也称局域网地址

Mac地址也称物理地址,硬件地址,由网络设备制造商生产时烧录在网卡上
Mac是制造商为网络硬件(如无线网卡或以太网卡)分配的唯一地址,
Mac代表媒体访问控制,每个代码对应一个唯一的设备,
Mac地址为六组两位字符组成,由冒号分隔,比如:00:1B:44:11:3A:B7 
Mac地址用于确认一个网络设备位置的位址
在ISO模型中,第三层网络层负责IP地址,第二层链路层负责Mac位址
Mac地址用于在网络中标识一个唯一的网卡,一台设备如果由一个或者多个网卡,则每隔网卡都需要并会有一个唯一的MAC地址
————————————————
版权声明:本文为CSDN博主「火木火木」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/z972065491/article/details/127305222

2.如何获取MAC地址 代码(借鉴的):
#include "stdafx.h"
#include <windows.h>
#include <wincon.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <Nb30.h>
#pragma comment(lib, "netapi32.lib")

int GetMac(char* mac)
{
    NCB ncb;
    typedef struct _ASTAT_
     {
        ADAPTER_STATUS   adapt;
        NAME_BUFFER   NameBuff[30];
     }ASTAT, * PASTAT;

     ASTAT Adapter;

     typedef struct _LANA_ENUM
     {
        UCHAR   length;
        UCHAR   lana[MAX_LANA];
     }LANA_ENUM;

    LANA_ENUM lana_enum;
     UCHAR uRetCode;
     memset(&ncb, 0, sizeof(ncb));
     memset(&lana_enum, 0, sizeof(lana_enum));
     ncb.ncb_command = NCBENUM;
     ncb.ncb_buffer = (unsigned char*)&lana_enum;
     ncb.ncb_length = sizeof(LANA_ENUM);
     uRetCode = Netbios(&ncb);

     if (uRetCode != NRC_GOODRET)
         return uRetCode;

     for (int lana = 0; lana < lana_enum.length; lana++)
     {
        ncb.ncb_command = NCBRESET;
        ncb.ncb_lana_num = lana_enum.lana[lana];
        uRetCode = Netbios(&ncb);
         if (uRetCode == NRC_GOODRET)
             break;
     }

     if (uRetCode != NRC_GOODRET)
         return uRetCode;

     memset(&ncb, 0, sizeof(ncb));
     ncb.ncb_command = NCBASTAT;
     ncb.ncb_lana_num = lana_enum.lana[0];
     strcpy((char*)ncb.ncb_callname, "*");
     ncb.ncb_buffer = (unsigned char*)&Adapter;
     ncb.ncb_length = sizeof(Adapter);
     uRetCode = Netbios(&ncb);

     if (uRetCode != NRC_GOODRET)
         return uRetCode;

     sprintf(mac, "%02X-%02X-%02X-%02X-%02X-%02X",
         Adapter.adapt.adapter_address[0],
         Adapter.adapt.adapter_address[1],
         Adapter.adapt.adapter_address[2],
         Adapter.adapt.adapter_address[3],
         Adapter.adapt.adapter_address[4],
         Adapter.adapt.adapter_address[5]);

    return 0;
 }
const char* GetMacPath(int argc, char* argv[])
{
     char   mac[200];
     GetMac(mac);
     
     return mac;
 }

二.遇到的两个编译问题

1.无法解析的外部符号 "public: virtual struct CRuntimeClass

原因和解决办法

法解析的外部符号 "public: virtual struct CRuntimeClass * __thiscall CMessageBox::GetRuntimeClass(void)const "

以下原因是会引起上述错误的:  
1,在.h文件中写了DECLARE_DYNAMIC,而在.cpp文件中没有写IMPLEMENT_DYNAMIC   
2,在.h文件中写了DECLARE_DYNCREATE ,但在.cpp文件中没有写上IMPLEMENT_DYNCREATE

在编写自定义类时,你必须知道,如果在类定义中包含了DECLARE_DYNAMIC,那你必须在类声明中包含IMPLEMENT_DYNAMIC;如果在类定义中包含了DECLARE_DYNCREATE,你必须在类声明中包含IMPLEMENT_DYNCREATE

.h类中定义

DECLARE_DYNCREATE(CMyWinThread)

DECLARE_MESSAGE_MAP()

.cpp类中定义

IMPLEMENT_DYNAMIC(CMyWinThread,CWinThread)  
BEGIN_MESSAGE_MAP(CMyWinThread, CWinThread)   
END_MESSAGE_MAP()

只需要记住:消息映射在.h文件和.cpp文件中是一一对应的。
————————————————
版权声明:本文为CSDN博主「changbaolong」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/changbaolong/article/details/8479775

2.CString与LPCWSTR、LPSTR、char*、LPWSTR等类型的转换 (UNICODE版本字符串转换为Ansi版本)
一.CString与LPCWSTR

两者的不同:LPCWSTR 是Unicode字符串指针,初始化时串有多大,申请空间就有多大,以后存贮若超过则出现无法预料的结果,这是它与CString的不同之处。而CString是一个串类,内存空间类会自动管理。

CString转换成LPCWSTR

方法一:

CString strFileName;

LPCWSTR lpcwStr = strFileName.AllocSysString();

方法二:

CString str=_T("TestStr");
       USES_CONVERSION;
       LPCWSTR lpcwStr = A2CW((LPCSTR)str);

MFC中CString和LPSTR是可以通用,其中A2CW表示(LPCSTR) -> (LPCWSTR),USER_CONVERSION表示用来定义一些中间变量,在使用ATL的转换宏之前必须定义该语句。

LPCWSTR转换成CString

LPCWSTR lpcwStr = L"TestWStr";
       CString str(lpcwStr);

二.CString与LPSTR转换
CString转换成LPSTR:

方法一:

CString strFileName;

LPSTR lpStr = strFileName.GetBuffer();

strFileName.ReleaseBuffer();

方法二:

CString strFileName;

LPSTR lpStr = (LPSTR)(LPCSTR)strFimeName;

LPSTR转换成CString:

LPSTR lpStr = L"TestStr";
       CString str(lpStr);

注意:CString和LPCSTR可直接转换,如下:

CString str;

LPCSTR lpcStr = (LPCSTR)str;

三.CString和char*转换

CString转换成char*


方法一:

CString str;
       char* p = str.GetBuffer();
方法二:

CString str;
       char* p = (LPSTR)(LPCSTR)str;


char*转换成CString


char* p = "test";
CString str = ("%s",p);

四.String和int、float的转换

可以使用atoi,atof,atol等函数来完成。

五.LPSTR(char*)和LPWSTR的转换

可以使用下面的ATL宏来进行,最好是将变量定义成TCHAR、LPTSTR等T类型,可以避免转换。

ATL宏介绍:

A2BSTR OLE2A T2A W2A
A2COLE OLE2BSTR T2BSTR W2BSTR
A2CT OLE2CA T2CA W2CA
A2CW OLE2CT T2COLE W2COLE
A2OLE OLE2CW T2CW W2CT
A2T OLE2T T2OLE W2OLE
A2W OLE2W T2W W2T

A :ANSI 字符串,也就是 MBCS。
W、OLE 宽字符串,也就是 UNICODE。
T 中间类型T。如果定义了 _UNICODE,则T表示W;如果定义了 _MBCS,则T表示A
C const 的缩写

利用这些宏,可以快速的进行各种字符间的转换。使用前必须包含头文件,并且申明USER_CONVERSION;使用 ATL 转换宏,由于不用释放临时空间,所以使用起来非常方便。但是考虑到栈空间的尺寸(VC 默认2M),使用时要注意几点:

1、只适合于进行短字符串的转换;
2、不要试图在一个次数比较多的循环体内进行转换;
3、不要试图对字符型文件内容进行转换,因为文件尺寸一般情况下是比较大的;
4、对情况 2 和 3,要使用 MultiByteToWideChar() 和 WideCharToMultiByte();

void Func1(LPSTR lpStr);

void Func2(LPWSTR lpwStr);

TCHAR name[256];

TCHAR* pName = new TCHAR[256];

Func1(name); // Func1(pName);

Func2(name); // Func2(pName);

注意在VS2005中上面用红色标记的代码已经不成立。

VS2005中CString已经改为宽字符型,一些转换如下:

char name[10];
TCHAR sex[5] ;
char *p = name;
TCHAR *pw = sex;
LPSTR lpstr = name;
LPCSTR lpcstr = name;
lpcstr = lpstr;
lpstr = p;
p = (char*)sex;
pw = (WCHAR*)name;
LPWSTR lpwstr = (LPWSTR)lpstr;
lpwstr = (LPWSTR)lpcstr;
LPCWSTR lpcwstr = (LPCWSTR)lpstr;
lpcwstr = (LPCWSTR)name;
CString str(lpstr);
CString str1(lpcstr);
CString str2(lpwstr);
CString str3(lpcwstr);
CString str4(name);
CString str5(sex);
lpwstr = (LPWSTR)(LPCWSTR)str;
lpstr = (LPSTR)(LPCWSTR)str;
lpcstr = (LPCSTR)(LPCWSTR)str;
p = (char*)str.GetBuffer();
pw = str.GetBuffer();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学伟!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值