您的足迹:首页 > 经验技术 >QQPC端原生创建和使用CTXString类

QQPC端原生创建和使用CTXString类

做QQ插件这么多年了,在我年幼无知的时候曾经写过一篇文章:http://lance.moe/post-181.html
当时是2011年,初一刚毕业在上初二,而且有不少基佬都在写QQ插件,大家其乐融融探讨气氛很浓,转眼都过去四五年了,实在是太快了。
    以上都是题外话,我们步入今天的内容:
如何原生创建QQ客户端的CTXStringW和CTXStringA类?
    我们注意到,QQ的许多函数都是需要用到这两个类的,其实这两个类类似于ATL提供的CString,功能上起码是基本一样的,具体怎么实现的不是今天的研究话题,我们的话题是如何去用。
    众所周知,QQ2009以后至今的QQPC客户端都是COM架构的,QQ内部无非就两大种class,一种是C++的class,另一种是COM包装的虚函数class,以C开头的是C++的class类(如CTXStringW、CTXBSTR等),以I开头的是COM类(比如ITXData、ITXMsgPack等)。
    COM是种古老的技术了,但是至今它的思想还是不过时,早期OSXQQ、LinuxQQ都是腾讯在其他平台模拟COM做成的,基本可以很方便的移植代码,但是很遗憾这种思想没有坚持下去,也许是因为本身COM就是一种比较复杂的实现,在今天可以有更多更简单的实现方式。

我们知道COM的导出类其实就是一张虚函数表,在COM服务中注册后,我们只需要通过一个GUID就可以创建了,那么QQ中C类是怎么创建的呢?
    其实很简单,C类没法“凭空”创建,所以QQ客户端里这种C打头的class,只是通过导出表的形式导出了而已,这个CTXStringW和CTXStringA就是在Common.dll中导出的,那么怎么创建和调用?
    其实也很简单,我们只需要通过QQ的DLL生成LIB伪静态库即可,生成方法我贴个BAT脚本:
set DLLNAME=Common
pexports %DLLNAME%.dll > %DLLNAME%.def
lib /def:%DLLNAME%.def /machine:i386 /out:%DLLNAME%.lib
pause
运行这段代码你需要安装过VS,而且设置好环境路径,具体怎么设置,网上搜一下就知道了,不再浪费口舌。
然后就是得知里面这个类怎么引入?网上有许多导出器可以用,搜索一下就可以得到答案,我直接贴出我做好的:
#pragma comment(lib, "Common.lib")
#define DLLIMPORT __declspec(dllimport)

class DLLIMPORT CTXBSTR
{
public:
	CTXBSTR(class CTXStringW const &);
	CTXBSTR(int);
	CTXBSTR(int,wchar_t const *);
	CTXBSTR(struct _GUID const &);
	CTXBSTR(void);
	CTXBSTR(wchar_t const *);
	bool operator!=(class CTXBSTR const &)const;
	bool operator!=(wchar_t *)const;
	bool operator!=(wchar_t const *)const;
	bool operator<(class CTXBSTR const &)const;
	bool operator<(wchar_t *)const;
	bool operator<(wchar_t const *)const;
	bool operator==(class CTXBSTR const &)const;
	bool operator==(wchar_t *)const;
	bool operator==(wchar_t const *)const;
	bool operator>(class CTXBSTR const &)const;
	bool operator>(wchar_t *)const;
	bool operator>(wchar_t const *)const;
	class CTXBSTR & operator+=(class CTXBSTR const &);
	class CTXBSTR & operator+=(class CTXStringW const &);
	class CTXBSTR & operator+=(wchar_t const *);
	class CTXBSTR & operator=(class CTXBSTR const &);
	class CTXBSTR & operator=(class CTXStringW const &);
	class CTXBSTR & operator=(wchar_t const *);
	int IsEmpty(void);
	int LoadStringW(struct HINSTANCE__ *,unsigned int);
	long Append(char);
	long Append(class CTXBSTR const &);
	long Append(wchar_t const *);
	long Append(wchar_t const *,int);
	long Append(wchar_t);
	long AppendBSTR(wchar_t *);
	long AppendBytes(char const *,int);
	long ArrayToBSTR(struct tagSAFEARRAY const *);
	long AssignBSTR(wchar_t * const);
	long BSTRToArray(struct tagSAFEARRAY * *);
	long CopyTo(struct tagVARIANT *)const;
	long CopyTo(wchar_t * *)const;
	long ReadFromStream(struct IStream *);
	long ToLower(void);
	long ToUpper(void);
	long WriteToStream(struct IStream *);
	operator wchar_t *(void)const;
	unsigned int ByteLength(void)const;
	unsigned int Length(void)const;
	void Attach(wchar_t *);
	void Empty(void);
	wchar_t * * operator&(void);
	wchar_t * Copy(void)const;
	wchar_t * Detach(void);
	~CTXBSTR(void);
};

class DLLIMPORT CTXStringA
{
public:
	CTXStringA(char const *);
	CTXStringA(char const *,int);
	CTXStringA(char,int);
	CTXStringA(struct tagEN,wchar_t const *,int);
	CTXStringA(struct tagGBK,wchar_t const *,int);
	CTXStringA(struct tagUTF8,wchar_t const *,int);
	CTXStringA(void);
	bool IsEmpty(void)const;
	bool operator!(void)const;
	char * GetBuffer(int);
	char * GetBuffer(void);
	char * GetBufferSetLength(int);
	char GetAt(int)const;
	char const * GetString(void)const;
	char operator[](int)const;
	class CTXStringA & MakeLower(void);
	class CTXStringA & MakeReverse(void);
	class CTXStringA & MakeUpper(void);
	class CTXStringA & Trim(char const *);
	class CTXStringA & Trim(char);
	class CTXStringA & Trim(void);
	class CTXStringA & TrimLeft(char const *);
	class CTXStringA & TrimLeft(char);
	class CTXStringA & TrimLeft(void);
	class CTXStringA & TrimRight(char const *);
	class CTXStringA & TrimRight(char);
	class CTXStringA & TrimRight(void);
	class CTXStringA & operator+=(char const *);
	class CTXStringA & operator+=(char);
	class CTXStringA & operator+=(class CTXStringA const &);
	class CTXStringA & operator=(char const *);
	class CTXStringA & operator=(char);
	class CTXStringA & operator=(class CTXStringA const &);
	class CTXStringA Left(int)const;
	class CTXStringA Mid(int)const;
	class CTXStringA Mid(int,int)const;
	class CTXStringA Right(int)const;
	int Compare(char const *)const;
	int CompareNoCase(char const *)const;
	int Delete(int,int);
	int Find(char const *,int)const;
	int Find(char,int)const;
	int FindOneOf(char const *)const;
	int GetAllocLength(void)const;
	int GetLength(void)const;
	int Insert(int,char const *);
	int Insert(int,char);
	int Remove(char);
	int Replace(char const *,char const *);
	int Replace(char,char);
	int ReverseFind(char)const;
	operator char const *(void)const;
	void Append(char const *);
	void Append(char const *,int);
	void Append(class CTXStringA const &);
	void AppendChar(char);
	void Empty(void);
	void Format(char const *,...);
	void FormatV(char const *,char *);
	void Preallocate(int);
	void ReleaseBuffer(int);
	void SetAt(int,char);
	void SetString(char const *);
	void SetString(char const *,int);
	void Truncate(int);
	~CTXStringA(void);
};

class DLLIMPORT CTXStringW
{
public:
	CTXStringW(class CTXBSTR const &);
	CTXStringW(int);
	CTXStringW(struct _GUID const &);
	CTXStringW(struct tagEN,char const *,int);
	CTXStringW(struct tagGBK,char const *,int);
	CTXStringW(struct tagUTF8,char const *,int);
	CTXStringW(struct tagVARIANT const &);
	CTXStringW(void);
	CTXStringW(wchar_t *);
	CTXStringW(wchar_t const *);
	CTXStringW(wchar_t const *,int);
	CTXStringW(wchar_t,int);
	bool IsEmpty(void)const;
	bool operator!(void)const;
	class CTXStringW & MakeLower(void);
	class CTXStringW & MakeReverse(void);
	class CTXStringW & MakeUpper(void);
	class CTXStringW & Trim(void);
	class CTXStringW & Trim(wchar_t const *);
	class CTXStringW & Trim(wchar_t);
	class CTXStringW & TrimLeft(void);
	class CTXStringW & TrimLeft(wchar_t const *);
	class CTXStringW & TrimLeft(wchar_t);
	class CTXStringW & TrimRight(void);
	class CTXStringW & TrimRight(wchar_t const *);
	class CTXStringW & TrimRight(wchar_t);
	class CTXStringW & operator+=(class CTXBSTR const &);
	class CTXStringW & operator+=(class CTXStringW const &);
	class CTXStringW & operator+=(struct tagVARIANT const &);
	class CTXStringW & operator+=(wchar_t const *);
	class CTXStringW & operator+=(wchar_t);
	class CTXStringW & operator=(class CTXBSTR const &);
	class CTXStringW & operator=(class CTXStringW const &);
	class CTXStringW & operator=(struct tagVARIANT const &);
	class CTXStringW & operator=(wchar_t *);
	class CTXStringW & operator=(wchar_t const *);
	class CTXStringW & operator=(wchar_t);
	class CTXStringW Left(int)const;
	class CTXStringW Mid(int)const;
	class CTXStringW Mid(int,int)const;
	class CTXStringW Right(int)const;
	class CTXStringW SpanIncluding(wchar_t const *)const;
	class CTXStringW Tokenize(wchar_t const *,int &)const;
	class CTXStringW const & Refresh(void)const;
	int Collate(wchar_t const *)const;
	int CollateNoCase(wchar_t const *)const;
	int Compare(wchar_t const *)const;
	int CompareNoCase(wchar_t const *)const;
	int Delete(int,int);
	int Find(wchar_t const *,int)const;
	int Find(wchar_t,int)const;
	int FindOneOf(wchar_t const *)const;
	int GetAllocLength(void)const;
	int GetByteLength(void)const;
	int GetLength(void)const;
	int Insert(int,wchar_t const *);
	int Insert(int,wchar_t);
	int LoadStringW(struct HINSTANCE__ *,unsigned int);
	int LoadStringW(struct HINSTANCE__ *,unsigned int,unsigned short);
	int Remove(wchar_t);
	int Replace(wchar_t const *,wchar_t const *);
	int Replace(wchar_t,wchar_t);
	int ReverseFind(wchar_t)const;
	operator wchar_t const *(void)const;
	void Append(class CTXStringW const &);
	void Append(wchar_t const *);
	void Append(wchar_t const *,int);
	void AppendBSTR(wchar_t *);
	void AppendChar(wchar_t);
	void AppendFormat(wchar_t const *,...);
	void Empty(void);
	void Format(wchar_t const *,...);
	void FormatV(wchar_t const *,char *);
	void Preallocate(int);
	void ReleaseBuffer(int);
	void SetAt(int,wchar_t);
	void SetString(wchar_t const *);
	void SetString(wchar_t const *,int);
	void Truncate(int);
	wchar_t * * GetBSTRPtr(void);
	wchar_t * AllocSysString(void)const;
	wchar_t * GetBSTR(void)const;
	wchar_t * GetBuffer(int);
	wchar_t * GetBuffer(void);
	wchar_t * GetBufferSetLength(int);
	wchar_t * SetSysString(wchar_t * *)const;
	wchar_t GetAt(int)const;
	wchar_t const * GetString(void)const;
	wchar_t operator[](int)const;
	~CTXStringW(void);
};

// 重载运算符
DLLIMPORT bool operator!=(char const *,class CTXStringA const &);
DLLIMPORT bool operator!=(char,class CTXStringA const &);
DLLIMPORT bool operator!=(class CTXStringA const &,char const *);
DLLIMPORT bool operator!=(class CTXStringA const &,char);
DLLIMPORT bool operator!=(class CTXStringA const &,class CTXStringA const &);
DLLIMPORT bool operator!=(class CTXStringW const &,class CTXStringW const &);
DLLIMPORT bool operator!=(class CTXStringW const &,wchar_t const *);
DLLIMPORT bool operator!=(class CTXStringW const &,wchar_t);
DLLIMPORT bool operator!=(wchar_t *,class CTXBSTR const &);
DLLIMPORT bool operator!=(wchar_t const *,class CTXBSTR const &);
DLLIMPORT bool operator!=(wchar_t const *,class CTXStringW const &);
DLLIMPORT bool operator!=(wchar_t,class CTXStringW const &);
DLLIMPORT bool operator<(char const *,class CTXStringA const &);
DLLIMPORT bool operator<(class CTXStringA const &,char const *);
DLLIMPORT bool operator<(class CTXStringA const &,class CTXStringA const &);
DLLIMPORT bool operator<(class CTXStringW const &,class CTXStringW const &);
DLLIMPORT bool operator<(class CTXStringW const &,wchar_t const *);
DLLIMPORT bool operator<(wchar_t const *,class CTXStringW const &);
DLLIMPORT bool operator<=(char const *,class CTXStringA const &);
DLLIMPORT bool operator<=(class CTXStringA const &,char const *);
DLLIMPORT bool operator<=(class CTXStringA const &,class CTXStringA const &);
DLLIMPORT bool operator<=(class CTXStringW const &,class CTXStringW const &);
DLLIMPORT bool operator<=(class CTXStringW const &,wchar_t const *);
DLLIMPORT bool operator<=(wchar_t const *,class CTXStringW const &);
DLLIMPORT bool operator==(char const *,class CTXStringA const &);
DLLIMPORT bool operator==(char,class CTXStringA const &);
DLLIMPORT bool operator==(class CTXStringA const &,char const *);
DLLIMPORT bool operator==(class CTXStringA const &,char);
DLLIMPORT bool operator==(class CTXStringA const &,class CTXStringA const &);
DLLIMPORT bool operator==(class CTXStringW const &,class CTXStringW const &);
DLLIMPORT bool operator==(class CTXStringW const &,wchar_t const *);
DLLIMPORT bool operator==(class CTXStringW const &,wchar_t);
DLLIMPORT bool operator==(wchar_t *,class CTXBSTR const &);
DLLIMPORT bool operator==(wchar_t *,class CTXStringW const &);
DLLIMPORT bool operator==(wchar_t const *,class CTXBSTR const &);
DLLIMPORT bool operator==(wchar_t const *,class CTXStringW const &);
DLLIMPORT bool operator==(wchar_t,class CTXStringW const &);
DLLIMPORT bool operator>(char const *,class CTXStringA const &);
DLLIMPORT bool operator>(class CTXStringA const &,char const *);
DLLIMPORT bool operator>(class CTXStringA const &,class CTXStringA const &);
DLLIMPORT bool operator>(class CTXStringW const &,class CTXStringW const &);
DLLIMPORT bool operator>(class CTXStringW const &,wchar_t const *);
DLLIMPORT bool operator>(wchar_t const *,class CTXStringW const &);
DLLIMPORT bool operator>=(char const *,class CTXStringA const &);
DLLIMPORT bool operator>=(class CTXStringA const &,char const *);
DLLIMPORT bool operator>=(class CTXStringA const &,class CTXStringA const &);
DLLIMPORT bool operator>=(class CTXStringW const &,class CTXStringW const &);
DLLIMPORT bool operator>=(class CTXStringW const &,wchar_t const *);
DLLIMPORT bool operator>=(wchar_t const *,class CTXStringW const &);
DLLIMPORT class CTXStringA operator+(char const *,class CTXStringA const &);
DLLIMPORT class CTXStringA operator+(char,class CTXStringA const &);
DLLIMPORT class CTXStringA operator+(class CTXStringA const &,char const *);
DLLIMPORT class CTXStringA operator+(class CTXStringA const &,char);
DLLIMPORT class CTXStringA operator+(class CTXStringA const &,class CTXStringA const &);
DLLIMPORT class CTXStringW operator+(class CTXStringW const &,class CTXStringW const &);
DLLIMPORT class CTXStringW operator+(class CTXStringW const &,wchar_t const *);
DLLIMPORT class CTXStringW operator+(class CTXStringW const &,wchar_t);
DLLIMPORT class CTXStringW operator+(wchar_t const *,class CTXStringW const &);
DLLIMPORT class CTXStringW operator+(wchar_t,class CTXStringW const &);
有了这些,我们就可以开始用了~我猜你想这么用:
CTXStringW pStr;
CTXStringW pStr2(L"小马哥");
pStr = L"我爱";
pStr += pStr2;
pStr += "\n";
wprintf(pStr.GetString());
然后程序就直接崩溃了...为什么会这样?难道是我们声明的函数有问题?
崩溃原因是因为初始化函数的缓冲区都在一起,简单说C语言的类就是这种特性,这么用的话,同一个区域会开辟两次,于是就崩了...我觉得有篇文章写的不错,想深究这个问题可以看看:http://blog.csdn.net/maksim_y/article/details/8302538

给大家贴出来我是这么用的,也比较方便:
CTXStringW &pStr = *new CTXStringW;
CTXStringW &pStr2 = *new CTXStringW(L"小马哥");
pStr = L"我爱";
pStr += pStr2;
wprintf(pStr.GetString()); //输出结果:我爱小马哥
delete &pStr; //会自动调用析构函数释放内存
delete &pStr2;
还有其他很多类用法基本都差不多,我只是抛砖引玉,欢迎大家继续探索~
本博客所有文章如无特别注明均为原创。作者:Lance.Moe复制或转载请以超链接形式注明转自 Lance's Blog
原文地址《QQPC端原生创建和使用CTXString类

相关推荐

发表评论

路人甲 表情
看不清楚?点图切换 Ctrl+Enter快速提交

网友评论(0)