2012-02-10 63 views
4

我对unsigned char(也是WinAPI中的​​)和char指针之间的差异有点困惑。无符号字符和char指针之间的区别

目前我正在与一些基于ATL的旧代码工作,我看到很多表情像下面这样:

CAtlArray<BYTE> rawContent; 
CALL_THE_FUNCTION_WHICH_FILLS_RAW_CONTENT(rawContent); 
return ArrayToUnicodeString(rawContent); 
// or return ArrayToAnsiString(rawContent); 

现在,ArrayToXXString的实现看看下面的方法:

CStringA ArrayToAnsiString(const CAtlArray<BYTE>& array) 
{ 
    CAtlArray<BYTE> copiedArray; 
    copiedArray.Copy(array); 
    copiedArray.Add('\0'); 

    // Casting from BYTE* -> LPCSTR (const char*). 
    return CStringA((LPCSTR)copiedArray.GetData()); 
} 

CStringW ArrayToUnicodeString(const CAtlArray<BYTE>& array) 
{ 
    CAtlArray<BYTE> copiedArray; 
    copiedArray.Copy(array); 

    copiedArray.Add('\0'); 
    copiedArray.Add('\0'); 

    // Same here.   
    return CStringW((LPCWSTR)copiedArray.GetData()); 
} 

所以,问题:

  • 是从BYTE*的C样式转换到LPCSTRconst char*)安全的所有可能的情况?

  • 是否真的需要添加double将数组数据转换为宽字符串时是否为空终止?

  • 转换例程CStringW((LPCWSTR)copiedArray.GetData())对我来说似乎是无效的,这是真的吗?

  • 任何方式使所有这些代码更容易理解和维护?

回答

3

当谈到定义一个字节时,C标准有点奇怪。尽管如此,你确实有一些保证。

  • 字节总是会在大小一个字符
    • 的sizeof(char)的始终返回1
  • 一个字节将是在尺寸上

该定义至少8位与旧的平台没有很好的匹配,其中一个字节长度为6或7位,但这确实意味着BYTE*,char *保证等效。

在Unicode字符串的末尾需要多个空值,因为存在以零(空)字节开头的有效Unicode字符。

至于让代码更容易阅读,那完全是风格问题。这段代码似乎是用很多旧的C代码所使用的风格编写的,而这些C代码肯定已经不受欢迎了。可能有很多方法可以让你更清楚,但如何更清楚地说明并没有明确的答案。

2
  • 是的,它始终是安全的。因为它们都指向一组单字节内存位置。
    LPCSTR:长指针为const(单字节)字符串
    LPCWSTR:长指针CONST宽(多字节)字符串
    LPCTSTR:长指针CONST依赖于上下文的(单字节或多字节)字符串

  • 在宽字符字符串中,每个单个字符占用2个字节的内存,并且包含该字符串的内存位置的长度必须是2的倍数。因此,如果要将宽度'\ 0'添加到字符串的末尾,您应该添加两个字节。

  • 对不起,对于这部分,我不知道ATL,在这部分我不能帮你,但实际上我没有看到复杂性,我认为这很容易维护。你真的想让哪些代码更容易理解和维护?

1
  1. 如果BYTE *就像一个适当的字符串(即最后一个字节为0),可以投一个BYTE *一个LPCSTR,是的。使用LPCSTR的函数假定零终止的字符串。
  2. 我认为只有在处理一些多字节字符集时,多个零才是必需的。最常见的8位编码(如普通的Windows Western和UTF-8)不需要它们。
  3. CString是Microsoft对用户友好字符串的最佳尝试。例如,它的构造函数可以处理charwchar_t类型的输入,而不管CString本身是否宽阔,所以你不必担心转换太多。

编辑:等待,现在我看到他们滥用BYTE数组来存储宽字符。我不能推荐这个。

0

LPCWSTR是一个字符串,每个字符有2个字节,“char”是每个字符一个字节。这意味着你不能使用C风格,因为你必须调整内存(在每个标准ASCII之前加一个“0”),而不是以不同于内存的方式读取数据(什么是C-Cast会做)。 所以演员阵容不是很安全,我会说。

The Double-Nulltermination:您总是有2个字节作为一个字符,所以您的“字符串结束”符号必须是2个字节长。

为了使代码更容易理解在加速的lexical_cast(http://www.boost.org/doc/libs/1_48_0/doc/html/boost_lexical_cast.html)照顾

另一种方法是使用std :: strings(使用类似std :: basic_string;),你可以在String操作上执行。

相关问题