前一阵子用系统的BSTR构造函数SysAllocString来模拟CTXStringW,但是结果是不稳定。什么是不稳定?就是有时候可以,有时候崩溃。用过FineIP早期版本的童鞋都知道FineIP是第一个可以在框内显示的辅助工具,而FineIP超级稳定,几乎没出现过崩溃的现象,几乎和QQ融为一体。这是为神马呢?
首先我们要了解BSTR,BSTR是BasicString的简写,是一种COM通用的字符串结构。
简介下BSTR的结构:
一个INT32来表示文本长度,一个wchar_t是宽字符串数据,用结构体表示为:
1
2
3
4
5
| typedef struct MyBSTR
{
DWORD dwLen;//表示长度
wchar_t strBuff[4100];//宽文本字符串数据
};
|
比如:L"我是1颗白菜",相对应的文本长度应该是12,那么Len就等于12,下面的StrBuff就对应是L"我是1颗白菜"。
下面是模仿系统的SysAllocString函数生成一个BSTR的源码:
1
2
3
4
5
6
7
8
9
10
| BSTR AllocBasicString(const wchar_t * lpSrc)
{
if(lpSrc == NULL) return NULL;
BYTE * bBuffer = new BYTE[4+(wcslen(lpSrc)+1)*2];
if(bBuffer == NULL) return NULL;
DWORD dwLenth = wcslen(lpSrc)+1;
memmove(bBuffer,&dwLenth,4);
wcscpy((wchar_t *)(bBuffer+4),lpSrc);
return BSTR(bBuffer+4);
}
|
为神马返回的是buf1+4而不是直接buf1?因为BSTR其实表面上他就是wchar_t *,程序在找字符串长度时直接寻找前方的数据以提高效率,而这个4正是一个DWORD的长度。
你可能会奇怪为什么我花这么大段落来写BSTR,其实CTXStringW就是BSTR,下面我们就来研究下CTXStringW与BSTR:
我先说下CTXStringW的结构:
一个为0的DWORD,一个为3的DWORD,两个DWORD表示长度,一个wchar_t是宽字符串数据,用结构体表示为:
1
2
3
4
5
6
7
8
| typedef struct CTXBSTR
{
DWORD pMemMan;//内存管理器,我们不需要,直接写0
DWORD dwCount;//这里是提醒QQ是否回收内存,如果是0肯定会回收引起崩溃,小于等于2也不稳定,我们就填3
DWORD dwLen2;//这里不管是不是长度都无所谓了,因为QQ的返回字符串都没这个
DWORD dwLen;//这里是宽字符的长度,wcslen返回一个数值就行
wchar_t strBuff[4100];
} TXStr,* pTXStr;
|
我相信上面你如果看懂的话你就发现,其实CTXStringW就是BSTR,前面三个DWORD仅仅是为了防止QQ回收内存导致崩溃,差别并不大,这就是为什么有时直接传SysAllocString函数生成的字符串有时可以通过的原因。
所以就直接将CTXStringW理解为BSTR即可
比如:L"我是1颗白菜",pMemMan=0,dwCount=3,相对应的文本长度应该是6,那么dwLen=12,下面的strBuff就对应是L"我是1颗白菜"。
下面是模仿生成CTXStringW的函数源码,返回值我就依旧是用BSTR了:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| //定义CTXStringW为BSTR
typedef BSTR CTXStringW;
CTXStringW AllocTXString(const wchar_t * lpSrc)
{
if(lpSrc == NULL) return NULL;
BYTE * bBuffer = new BYTE[16+(wcslen(lpSrc)+1)*2];
if(bBuffer == NULL) return NULL;
DWORD dwZero = 0;
DWORD dwCount = 3;
DWORD dwLenth = wcslen(lpSrc)+1;
memmove(bBuffer+0*4,&dwZero,4);
memmove(bBuffer+1*4,&dwCount,4);
memmove(bBuffer+2*4,&dwLenth,4);
memmove(bBuffer+3*4,&dwLenth,4);
wcscpy((wchar_t *)(bBuffer+4*4),lpSrc);
return CTXStringW(bBuffer+16);
}
|
PS:以上就是CTXStringW的分析,可能有出入之处,敬请大牛指出,同时也希望越来越多的童鞋加入QQ显IP软件的行列一同探究哦~
部分资料参考自互联网、山野哥(QQFun/QQYoo作者)、Morning(FinePlus/FineIP作者)之经验。