百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

网络通信1:字节流的封装 字节流方法

liebian365 2024-10-30 04:49 22 浏览 0 评论

在网络通讯中,数据在网络传输的格式常以字节流的形式进行,因此需要我们对字节流进行写入和读出的操作。在几乎其他所有语言中,网络数据的收发在利用类似send(或write)和recv(或read)的方法时并没有明显的流处理。需要借助流才可以完成。数据流(data stream)是一组有序,有起点和终点的字节的数据序列。包括输入流和输出流。很多语言常将数据流分为输入流(InputStream)和输出流(OutputStream)两类。输入流只能读不能写,而输出流只能写不能读。通常程序中使用输入流读出数据,输出流写入数据,就好像数据流入到程序并从程序中流出。

为了提高数据的传输效率,通常使用缓冲流(Buffered Stream),即为一个流配有一个缓冲区(buffer),一个缓冲区就是专门用于传输数据的内存块。当向一个缓冲流写入数据时,系统不直接发送到外部设备,而是将数据发送到缓冲区。缓冲区自动记录数据,当缓冲区满时,系统将数据全部发送到相应的设备。当从一个缓冲流中读取数据时,系统实际是从缓冲区中读取数据。当缓冲区空时,系统就会从相关设备自动读取数据,并读取尽可能多的数据充满缓冲区。缓冲字节输入输出流,相对于基础的字节流有更高的效率,而效率更高的原理在于用空间换取时间。 也就是说使用缓冲流的时候,会先把一定的数据放到缓冲区,也就是内存中,然后read的时候直接从缓冲区读取,这样就减少了读写磁盘文件的次数,从而减少读写时间。

根据上面的原理能否实现字节流构造器。兼容输入流,输出流,缓冲流的功能。便于数据的组织和传输。同时兼容HTTP协议,TCP协议,UDP协议兼容的字节流。代码功能越独立越便于兼容。

C++实现网络数据流读取类:Gk8ByteMaker.h

 
 //**************************************************************
 //@创建者:冰剑
 //@创建时间:2008年3月8日 17时17分
 //@功能描述①:网络数据流读取类:支持脚本中直接根据模板使用
 //@功能描述②:注意服务器JAVA的高低位问题
 //@功能描述③:
 //**************************************************************
 #ifndef __GK8NETBREADER_H__
 #define __GK8NETBREADER_H__
 ?
 #pragma once
 #include "Gk8Env.h"
 #include "Gk8PlatformDefine.h"
 #include "Gk8BaseObj.h"
 ?
 ?
 class Gk8ByteMaker:public Gk8BaseObj
 {
     DECLARE_TOSPP_MAP;  
 protected:
     GK8_LPBYTE m_pBuf;      //[数据缓存]
     GK8_INT m_nUseSize;     //[使用大小]
     GK8_INT m_nBufSize;     //[缓存分配大小]
     GK8_INT m_nReadPos;     //[读取位置]
 public:
     Gk8ByteMaker():m_pBuf(NULL),m_nReadPos(0),m_nUseSize(0),m_nBufSize(0){};
     ~Gk8ByteMaker();
 ?
     static Gk8ByteMaker* Create(Gk8BaseObj* pSuperObj=NULL);
 ?
     //[属性操作]
     TOSPP_MEMBER_INT_DECLARE(m_nReadPos,m_nReadPos)
     inline GK8_INT TOSPPFUNC GetStreamSize()const{return m_nUseSize;};
 ?
     GK8_LPBYTE WriteAlloc(GK8_INT nSize);
 ?
     //[读行为操作]
     GK8_BOOL Get(GK8_LPBYTE lpPtr,GK8_INT nLen)const;
     GK8_LPBYTE GetBuf(GK8_INT& nLen);
     inline GK8_LPBYTE GetBuf(){return m_pBuf;};
     inline operator GK8_LPBYTE (){return GetBuf();};
 ?
     GK8_VOID WriteBuf(GK8_LPCVOID lpPtr,GK8_INT nLen);
     GK8_VOID TOSPPFUNC WriteShort(GK8_INT nData);
     GK8_VOID TOSPPFUNC WriteInt(GK8_INT nData);
     GK8_VOID TOSPPFUNC WriteStr(GK8_LPCSTR lpStr);
 ?
     //[前面写入操作]
     GK8_VOID TOSPPFUNC WriteShortAt(GK8_INT nIndex,GK8_INT nData);
     GK8_VOID TOSPPFUNC WriteIntAt(GK8_INT nIndex,GK8_INT nData);
     GK8_VOID TOSPPFUNC WriteStrAt(GK8_INT nIndex,GK8_LPCSTR lpStr);
 ?
     //[读取操作]
     GK8_INT TOSPPFUNC ReadShort();
     GK8_INT TOSPPFUNC ReadInt();
     GK8_LPCSTR TOSPPFUNC ReadStr();
     GK8_LONG TOSPPFUNC ReadLong();
 ?
     //[其它行为操作]
     GK8_VOID ShiftTo(Gk8ByteMaker& iNetBReader);
     inline GK8_VOID SetReadPos(GK8_INT nReadPos){m_nReadPos=nReadPos;};
     inline GK8_VOID TOSPPFUNC ClearStream(){m_nUseSize=0;};
     GK8_VOID Pack();
     GK8_VOID Destroy();
 };
 #endif

C++实现网络数据流读取类:Gk8ByteMaker.cpp

 
 #include "Gk8ByteMaker.h"
 #include "Gk8MemSpy.h"
 #include "Gk8Str.h"
 #include "Gk8Helper.h"
 ?
 /////////////////////////////////////////////CLASS-TOLUA////////////////////////////////////////////////////
 TOLUA_CLASS_COLLECT_FUNC(Gk8ByteMaker)
 ?
 BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,Create)
     if(!CheckToLuaFunParam(L,"Create",Gk8Var()<<ISUSERTABLE("Gk8ByteMaker"))) return 0;
     Gk8BaseObj* pSuperObj=NULL;
     if(IFUSERTYPE(2,Gk8BaseObj)) pSuperObj=TOLUAGETOBJ(Gk8BaseObj,2);
     Gk8ByteMaker* pByteMaker=Gk8ByteMaker::Create(pSuperObj);
     toluafix_pushusertype_ccobject(L,TOLUAOBJID(pByteMaker),TOLUALPLUAID(pByteMaker),(GK8_LPVOID)pByteMaker,"Gk8ByteMaker");
 END_TOLUA_CLASS_FUNC
 ?
 BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,GetStreamSize)
     if(!CheckToLuaFunParam(L,"GetStreamSize",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISNOOBJ)) return 0;
     tolua_pushnumber(L,(lua_Number)TOLUAGETOBJ(Gk8ByteMaker,1)->GetStreamSize());
 END_TOLUA_CLASS_FUNC
 ?
 BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteShort)
     if(!CheckToLuaFunParam(L,"WriteShort",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISNUMBER<<ISNOOBJ)) return 0;
     TOLUAGETOBJ(Gk8ByteMaker,1)->WriteShort(TOLUAGETINT(2));
 END_TOLUA_CLASS_FUNC
 ?
 BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteInt)
     if(!CheckToLuaFunParam(L,"WriteInt",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISNUMBER<<ISNOOBJ)) return 0;
     TOLUAGETOBJ(Gk8ByteMaker,1)->WriteInt(TOLUAGETINT(2));
 END_TOLUA_CLASS_FUNC
 ?
 BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteStr)
     if(!CheckToLuaFunParam(L,"WriteStr",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISSTRING<<ISNOOBJ)) return 0;
     TOLUAGETOBJ(Gk8ByteMaker,1)->WriteStr(TOLUAGETSTRING(2));
 END_TOLUA_CLASS_FUNC
 ?
 BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteShortAt)
     if(!CheckToLuaFunParam(L,"WriteShortAt",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISNUMBER<<ISNUMBER<<ISNOOBJ)) return 0;
     TOLUAGETOBJ(Gk8ByteMaker,1)->WriteShortAt(TOLUAGETINT(2),TOLUAGETINT(3));
 END_TOLUA_CLASS_FUNC
 ?
 BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteIntAt)
     if(!CheckToLuaFunParam(L,"WriteIntAt",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISNUMBER<<ISNUMBER<<ISNOOBJ)) return 0;
     TOLUAGETOBJ(Gk8ByteMaker,1)->WriteIntAt(TOLUAGETINT(2),TOLUAGETINT(3));
 END_TOLUA_CLASS_FUNC
 ?
 BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteStrAt)
     if(!CheckToLuaFunParam(L,"WriteStrAt",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISSTRING<<ISNUMBER<<ISNOOBJ)) return 0;
     TOLUAGETOBJ(Gk8ByteMaker,1)->WriteStrAt(TOLUAGETINT(2),TOLUAGETSTRING(3));
 END_TOLUA_CLASS_FUNC
 ?
 BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,ReadShort)
     if(!CheckToLuaFunParam(L,"ReadShort",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISNOOBJ)) return 0;
     tolua_pushnumber(L,(lua_Number)TOLUAGETOBJ(Gk8ByteMaker,1)->ReadShort());
 END_TOLUA_CLASS_FUNC
 ?
 BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,ReadInt)
     if(!CheckToLuaFunParam(L,"ReadInt",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISNOOBJ)) return 0;
     tolua_pushnumber(L,(lua_Number)TOLUAGETOBJ(Gk8ByteMaker,1)->ReadInt());
 END_TOLUA_CLASS_FUNC
 ?
 BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,ReadStr)
     if(!CheckToLuaFunParam(L,"ReadStr",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISNOOBJ)) return 0;
     tolua_pushstring(L,TOLUAGETOBJ(Gk8ByteMaker,1)->ReadStr());
 END_TOLUA_CLASS_FUNC
 ?
 BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,ReadLong)
     if(!CheckToLuaFunParam(L,"ReadLong",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISNOOBJ)) return 0;
     tolua_pushnumber(L,(lua_Number)TOLUAGETOBJ(Gk8ByteMaker,1)->ReadLong());
 END_TOLUA_CLASS_FUNC
 ?
 BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,SetReadPos)
     if(!CheckToLuaFunParam(L,"SetReadPos",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISNUMBER<<ISNOOBJ)) return 0;
     TOLUAGETOBJ(Gk8ByteMaker,1)->SetReadPos(TOLUAGETINT(2));
 END_TOLUA_CLASS_FUNC
 ?
 BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,ClearStream)
     if(!CheckToLuaFunParam(L,"ClearStream",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISNOOBJ)) return 0;
     TOLUAGETOBJ(Gk8ByteMaker,1)->ClearStream();
 END_TOLUA_CLASS_FUNC
 //[启动注册类的全部TOLUA函数]
 BEGIN_TOLUA_FUN_MAP(Gk8ByteMaker)
     TOLUA_CLASS(Gk8ByteMaker,"","[]","[]")
     TOLUA_CLASS_FUNC(Gk8ByteMaker,Create,"[Gk8ByteMaker* Create(pSuperObj=NULL)?创建对象]")
     TOLUA_CLASS_FUNC(Gk8ByteMaker,GetStreamSize,"[]")
     TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteShort,"[]")
     TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteInt,"[]")
     TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteStr,"[]")
     TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteShortAt,"[]")
     TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteIntAt,"[]")
     TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteStrAt,"[]")
     TOLUA_CLASS_FUNC(Gk8ByteMaker,ReadShort,"[]")
     TOLUA_CLASS_FUNC(Gk8ByteMaker,ReadInt,"[]")
     TOLUA_CLASS_FUNC(Gk8ByteMaker,ReadStr,"[]")
     TOLUA_CLASS_FUNC(Gk8ByteMaker,ReadLong,"[]")
     TOLUA_CLASS_FUNC(Gk8ByteMaker,SetReadPos,"[]")
     TOLUA_CLASS_FUNC(Gk8ByteMaker,ClearStream,"[]")
 END_TOLUA_FUN_MAP
 ?
 /////////////////////////////////////////////CLASS-TOSPP////////////////////////////////////////////////////
 BEGIN_TOSPP_MAP(Gk8ByteMaker,Gk8BaseObj)
     TOSPP_INT(Gk8ByteMaker,m_nReadPos,"m_nReadPos" ,"")
     TOSPP_FUNC(Gk8ByteMaker,GetStreamSize,'d'," ","GetStreamSize()")
     TOSPP_FUNC(Gk8ByteMaker,WriteShort,' ',"d","WriteShort(nData)")
     TOSPP_FUNC(Gk8ByteMaker,WriteInt,' ',"d","WriteInt(nData)")
     TOSPP_FUNC(Gk8ByteMaker,WriteStr,' ',"s","WriteStr(lpStr)")
     TOSPP_FUNC(Gk8ByteMaker,WriteShortAt,' ',"dd","WriteShortAt(nIndex,nData)")
     TOSPP_FUNC(Gk8ByteMaker,WriteIntAt,' ',"dd","WriteIntAt(nIndex,nData)")
     TOSPP_FUNC(Gk8ByteMaker,WriteStrAt,' ',"ds","WriteStrAt(nIndex,lpStr)")
     TOSPP_FUNC(Gk8ByteMaker,ReadShort,'d'," ","ReadShort()")
     TOSPP_FUNC(Gk8ByteMaker,ReadInt,'d'," ","ReadInt()")
     TOSPP_FUNC(Gk8ByteMaker,ReadStr,'s'," ","ReadStr()")
     TOSPP_FUNC(Gk8ByteMaker,ReadLong,'P'," ","ReadLong()")
     TOSPP_FUNC(Gk8ByteMaker,ClearStream,' '," ","ClearStream()")
 END_TOSPP_MAP()
 ?
 ///////////////////////////[网络二进制读取逻辑]///////////////////
 Gk8ByteMaker::~Gk8ByteMaker()
 {
     if(m_pBuf) _Gk8Free(m_pBuf);
 }
 Gk8ByteMaker* Gk8ByteMaker::Create(Gk8BaseObj* pSuperObj)
 {
     Gk8ByteMaker* pByteMaker=new Gk8ByteMaker();
     if(pSuperObj) pByteMaker->SetSuper(pSuperObj);
     return pByteMaker;
 }
 ?
 TOSPP_MEMBER_INT_FUN(Gk8ByteMaker,m_nReadPos,m_nReadPos)
 //[提前增加指定长度的内存块]
 GK8_LPBYTE Gk8ByteMaker::WriteAlloc(GK8_INT nSize)
 {
     if(nSize>=1)
     {
         if(nSize+m_nUseSize>=m_nBufSize)
         {
             GK8_UINT nNewSize;
             m_pBuf=(GK8_LPBYTE)_Gk8ReAlloc(m_pBuf,m_nUseSize+nSize+32,nNewSize);
             m_nBufSize=nNewSize;
         }
         m_nUseSize+=nSize;
         return m_pBuf+m_nUseSize-nSize;
     }
     return NULL;
 }
 ?
 //[获取指定长度的二进制数据]
 GK8_BOOL Gk8ByteMaker::Get(GK8_LPBYTE lpPtr,GK8_INT nLen)const
 {
     if(m_nUseSize>=nLen) memcpy(lpPtr,m_pBuf,nLen);
     return true;
 }
 //[获取数据的内存指针]
 GK8_LPBYTE Gk8ByteMaker::GetBuf(GK8_INT& nLen)
 {
     nLen=m_nUseSize;
     return m_pBuf;
 }
 ?
 //[增加指定长度的二进制数据]
 GK8_VOID Gk8ByteMaker::WriteBuf(GK8_LPCVOID lpPtr,GK8_INT nLen)
 {
     GK8_LPBYTE pMem=WriteAlloc(nLen);
     memcpy(pMem,lpPtr,nLen);
 }
 ?
 GK8_VOID Gk8ByteMaker::WriteShort(GK8_INT nData)
 {
     GK8_LPBYTE pMem=WriteAlloc(sizeof(GK8_WORD));
     GK8_LPBYTE pDataMem=(GK8_LPBYTE)&nData;
     pMem[0]=pDataMem[1];
     pMem[1]=pDataMem[0];
 }
 ?
 GK8_VOID Gk8ByteMaker::WriteInt(GK8_INT nData)
 {
     GK8_LPBYTE pMem=WriteAlloc(sizeof(GK8_INT));
     GK8_LPBYTE pDataMem=(GK8_LPBYTE)&nData;
     pMem[0]=pDataMem[3];
     pMem[1]=pDataMem[2];
     pMem[2]=pDataMem[1];
     pMem[3]=pDataMem[0];
 }
 ?
 GK8_VOID Gk8ByteMaker::WriteStr(GK8_LPCSTR lpStr)
 {
     Gk8Str iStr=lpStr;
     WriteShort(iStr.GetLength());
     WriteBuf(iStr,iStr.GetLength());
 }
 ?
 GK8_VOID Gk8ByteMaker::WriteShortAt(GK8_INT nIndex,GK8_INT nData)
 {
     GK8_INT nLen=sizeof(GK8_WORD);
     WriteAlloc(nLen);
     memmove(m_pBuf+nIndex+nLen,m_pBuf+nIndex,m_nUseSize-nLen-nIndex);
     GK8_LPBYTE pDataMem=(GK8_LPBYTE)&nData;
     m_pBuf[nIndex]=pDataMem[1];
     m_pBuf[nIndex+1]=pDataMem[0];
 }
 ?
 GK8_VOID Gk8ByteMaker::WriteIntAt(GK8_INT nIndex,GK8_INT nData)
 {
     GK8_INT nLen=sizeof(GK8_INT);
     WriteAlloc(nLen);
     memmove(m_pBuf+nIndex+nLen,m_pBuf+nIndex,m_nUseSize-nLen-nIndex);
 ?
     GK8_LPBYTE pDataMem=(GK8_LPBYTE)&nData;
     m_pBuf[nIndex]=pDataMem[3];
     m_pBuf[nIndex+1]=pDataMem[2];
     m_pBuf[nIndex+2]=pDataMem[1];
     m_pBuf[nIndex+3]=pDataMem[0];
 }
 ?
 GK8_VOID Gk8ByteMaker::WriteStrAt(GK8_INT nIndex,GK8_LPCSTR lpStr)
 {
     Gk8Str iStr=lpStr;
     GK8_INT nStrLen=iStr.GetLength();
     GK8_INT nLen=sizeof(GK8_WORD)+nStrLen;
     WriteAlloc(nLen);
     memmove(m_pBuf+nIndex+nLen,m_pBuf+nIndex,m_nUseSize-nLen-nIndex);
     GK8_LPBYTE pDataMem=(GK8_LPBYTE)&nStrLen;
     m_pBuf[nIndex]=pDataMem[1];
     m_pBuf[nIndex+1]=pDataMem[0];
     memcpy(m_pBuf+nIndex+sizeof(GK8_WORD),iStr,nStrLen);
 }
 ?
 GK8_INT Gk8ByteMaker::ReadShort()
 {
     if(m_nReadPos>m_nUseSize-sizeof(GK8_WORD)) return NULL;
     GK8_INT nData;
     GK8_LPBYTE pDataMem=(GK8_LPBYTE)&nData;
     memset(pDataMem,0,sizeof(GK8_INT));
     pDataMem[1]=m_pBuf[m_nReadPos];
     pDataMem[0]=m_pBuf[m_nReadPos+1];
     m_nReadPos+=sizeof(GK8_WORD);
     return nData;
 }
 ?
 GK8_INT Gk8ByteMaker::ReadInt()
 {
     if(m_nReadPos>m_nUseSize-sizeof(GK8_INT)) return 0;
     GK8_INT nData;
     GK8_LPBYTE pDataMem=(GK8_LPBYTE)&nData;
     memset(pDataMem,0,sizeof(GK8_INT));
     pDataMem[3]=m_pBuf[m_nReadPos];
     pDataMem[2]=m_pBuf[m_nReadPos+1];
     pDataMem[1]=m_pBuf[m_nReadPos+2];
     pDataMem[0]=m_pBuf[m_nReadPos+3];
     m_nReadPos+=sizeof(GK8_INT);
     return nData;
 }
 ?
 GK8_LPCSTR Gk8ByteMaker::ReadStr()
 {
     if(m_nReadPos>m_nUseSize-sizeof(GK8_WORD)) return NULL;
     GK8_INT nLen;
     GK8_LPBYTE pDataMem=(GK8_LPBYTE)&nLen;
     memset(pDataMem,0,sizeof(GK8_INT));
     pDataMem[1]=m_pBuf[m_nReadPos];
     pDataMem[0]=m_pBuf[m_nReadPos+1];
     m_nReadPos+=sizeof(GK8_WORD);
     Gk8Str iStr;
     iStr.SetStr((GK8_LPCSTR)(m_pBuf+m_nReadPos),nLen);
     m_nReadPos+=nLen;
     return iStr;
 }
 ?
 GK8_LONG Gk8ByteMaker::ReadLong()
 {
     return 0;
 }
 //[克隆到另外一个实体中]
 GK8_VOID Gk8ByteMaker::ShiftTo(Gk8ByteMaker& iBReader)
 {
     iBReader.Destroy();
     iBReader.m_pBuf=m_pBuf;
     iBReader.m_nUseSize=m_nUseSize;
     iBReader.m_nBufSize=m_nBufSize;
     iBReader.m_nReadPos=m_nReadPos;
     m_pBuf=NULL;
     m_nBufSize=0;
     m_nUseSize=0;
     m_nReadPos=0;
 }
 //[整理数据:前面有内存已读取后面空余前移动]
 GK8_VOID Gk8ByteMaker::Pack()
 {
     if(m_nReadPos==m_nUseSize)
     {
         m_nUseSize=0;
         m_nReadPos=0;
         return;
     }
     memmove(m_pBuf,m_pBuf+m_nReadPos,m_nUseSize-m_nReadPos);
     m_nUseSize-=m_nReadPos;
     m_nReadPos=0;
 }
 //[销毁]
 GK8_VOID Gk8ByteMaker::Destroy()
 {
     if(m_pBuf) _Gk8Free(m_pBuf);
     m_pBuf=NULL;
     m_nUseSize=0;
     m_nBufSize=0;
     m_nReadPos=0;
 }


相关推荐

“版本末期”了?下周平衡补丁!国服最强5套牌!上分首选

明天,酒馆战棋就将迎来大更新,也聊了很多天战棋相关的内容了,趁此机会,给兄弟们穿插一篇构筑模式的卡组推荐!老规矩,我们先来看10职业胜率。目前10职业胜率排名与一周前基本类似,没有太多的变化。平衡补丁...

VS2017 C++ 程序报错“error C2065:“M_PI”: 未声明的标识符&quot;

首先,程序中头文件的选择,要选择头文件,在文件中是没有对M_PI的定义的。选择:项目——>”XXX属性"——>配置属性——>C/C++——>预处理器——>预处理器定义,...

东营交警实名曝光一批酒驾人员名单 88人受处罚

齐鲁网·闪电新闻5月24日讯酒后驾驶是对自己和他人生命安全极不负责的行为,为守护大家的平安出行路,东营交警一直将酒驾作为重点打击对象。5月23日,东营交警公布最新一批饮酒、醉酒名单。对以下驾驶人醉酒...

Qt界面——搭配QCustomPlot(qt platform)

这是我第一个使用QCustomPlot控件的上位机,通过串口精确的5ms发送一次数据,再将读取的数据绘制到图表中。界面方面,尝试卡片式设计,外加QSS简单的配了个色。QCustomPlot官网:Qt...

大话西游2分享赢取种族坐骑手办!PK趣闻录由你书写

老友相聚,仗剑江湖!《大话西游2》2021全民PK季4月激燃打响,各PK玩法鏖战齐开,零门槛参与热情高涨。PK季期间,不仅各种玩法奖励丰厚,参与PK趣闻录活动,投稿自己在PK季遇到的趣事,还有机会带走...

测试谷歌VS Code AI 编程插件 Gemini Code Assist

用ClaudeSonnet3.7的天气测试编码,让谷歌VSCodeAI编程插件GeminiCodeAssist自动编程。生成的文件在浏览器中的效果如下:(附源代码)VSCode...

顾爷想知道第4.5期 国服便利性到底需优化啥?

前段时间DNF国服推出了名为“阿拉德B计划”的系列改版计划,截至目前我们已经看到了两项实装。不过关于便利性上,国服似乎还有很多路要走。自从顾爷回归DNF以来,几乎每天都在跟我抱怨关于DNF里面各种各样...

掌握Visual Studio项目配置【基础篇】

1.前言VisualStudio是Windows上最常用的C++集成开发环境之一,简称VS。VS功能十分强大,对应的,其配置系统较为复杂。不管是对于初学者还是有一定开发经验的开发者来说,捋清楚VS...

还嫌LED驱动设计套路深?那就来看看这篇文章吧

随着LED在各个领域的不同应用需求,LED驱动电路也在不断进步和发展。本文从LED的特性入手,推导出适合LED的电源驱动类型,再进一步介绍各类LED驱动设计。设计必读:LED四个关键特性特性一:非线...

Visual Studio Community 2022(VS2022)安装图文方法

直接上步骤:1,首先可以下载安装一个VisualStudio安装器,叫做VisualStudioinstaller。这个安装文件很小,很快就安装完成了。2,打开VisualStudioins...

Qt添加MSVC构建套件的方法(qt添加c++11)

前言有些时候,在Windows下因为某些需求需要使用MSVC编译器对程序进行编译,假设我们安装Qt的时候又只是安装了MingW构建套件,那么此时我们该如何给现有的Qt添加一个MSVC构建套件呢?本文以...

Qt为什么站稳c++GUI的top1(qt c)

为什么现在QT越来越成为c++界面编程的第一选择,从事QT编程多年,在这之前做C++界面都是基于MFC。当时为什么会从MFC转到QT?主要原因是MFC开发界面想做得好看一些十分困难,引用第三方基于MF...

qt开发IDE应该选择VS还是qt creator

如果一个公司选择了qt来开发自己的产品,在面临IDE的选择时会出现vs或者qtcreator,选择qt的IDE需要结合产品需求、部署平台、项目定位、程序猿本身和公司战略,因为大的软件产品需要明确IDE...

Qt 5.14.2超详细安装教程,不会来打我

Qt简介Qt(官方发音[kju:t],音同cute)是一个跨平台的C++开库,主要用来开发图形用户界面(GraphicalUserInterface,GUI)程序。Qt是纯C++开...

Cygwin配置与使用(四)——VI字体和颜色的配置

简介:VI的操作模式,基本上VI可以分为三种状态,分别是命令模式(commandmode)、插入模式(Insertmode)和底行模式(lastlinemode),各模式的功能区分如下:1)...

取消回复欢迎 发表评论: