网络通信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”: 未声明的标识符"
-
首先,程序中头文件的选择,要选择头文件,在文件中是没有对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)...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- “版本末期”了?下周平衡补丁!国服最强5套牌!上分首选
- VS2017 C++ 程序报错“error C2065:“M_PI”: 未声明的标识符"
- 东营交警实名曝光一批酒驾人员名单 88人受处罚
- Qt界面——搭配QCustomPlot(qt platform)
- 大话西游2分享赢取种族坐骑手办!PK趣闻录由你书写
- 测试谷歌VS Code AI 编程插件 Gemini Code Assist
- 顾爷想知道第4.5期 国服便利性到底需优化啥?
- 掌握Visual Studio项目配置【基础篇】
- 还嫌LED驱动设计套路深?那就来看看这篇文章吧
- Visual Studio Community 2022(VS2022)安装图文方法
- 标签列表
-
- wireshark怎么抓包 (75)
- qt sleep (64)
- cs1.6指令代码大全 (55)
- factory-method (60)
- sqlite3_bind_blob (52)
- hibernate update (63)
- c++ base64 (70)
- nc 命令 (52)
- wm_close (51)
- epollin (51)
- sqlca.sqlcode (57)
- lua ipairs (60)
- tv_usec (64)
- 命令行进入文件夹 (53)
- postgresql array (57)
- statfs函数 (57)
- .project文件 (54)
- lua require (56)
- for_each (67)
- c#工厂模式 (57)
- wxsqlite3 (66)
- dmesg -c (58)
- fopen参数 (53)
- tar -zxvf -c (55)
- 速递查询 (52)