作者:更深的蓝
链接:https://www.zhihu.com/question/53686918/answer/136227041
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
CString
首先 CString 作为 MFC/ATL 标配的字符串类,是可以方便转换成字符串指针来用的,但注意这里有个小坑,就是某些答主提到的GetBuffer,不应该这么用。CString::GetBuffer 的作用,是锁定字符串缓冲区,得到一个可安全修改的指针,用完之后必须 ReleaseBuffer。如果只想把CString强转成const char *,考虑到你现在的编译环境是Unicode编码,分成几种情况。
CString str(“ABC”);
第一种
// 这种方法转出的指针,在 str 被修改前都是安全的,建议不要像这样保存指针,应即用即转。
const wchar_t * wp = (LPCTSTR)str;
const char *p = (LPCSTR)wp;
send(socket, p, 6, 0);
// 这样用更合理
send(socket, (LPCSTR)(LPCTSTR)str, 6, 0);
由于当前编译环境为 Unicode,CString 实际上是 CSringW,虽然强转成了 const char *,但你实际发出去的字符串是 "A\0B\0C\0"六个字节。
第二种
你就是想发出 "ABC"三个字节,那就必须用 API 把Unicode字符串转换成ANSI字符串再发送。
CString str1("ABC");
// 定义一个缓冲区来保存转换后的字符串
CStringA strA;
// 思考一下为什么长度要 *2
DWORD ansiLength = str1.GetLength() * 2;
// 把 Unicode 字符串转换为 ANSI 字符串,存入 StrA 中
WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)str1, -1, strA.GetBuffer(ansiLength), ansiLength, NULL, NULL);
// GetBuffer 必须 Release,否则后续操作无法进行
strA.ReleaseBuffer();
// 好了,现在可以安心发送了
send(socket, (LPCSTR)strA, strA.GetLength(), 0);
此时实际发送的的就是 "ABC"三个字节。PS: 虽然这个问题很基础,但其中涉及到内存布局、字符集、类型转换等问题,展开了讲一万字也包不住。即使像某些答主所言转成Qt,一样会踩到同样的坑,到时候恐怕来问的就是 QString 如何转换成 const char * 的问题了。所以,根本的解决问题还是好好啃书和搜索,遇到不明白的名词,就去搞清楚概念,这样才能真正掌握相关技术,而不是一步一磕。