我遇到了一个非常奇怪的问题......以下简单的测试代码如果在单个 Cocoa 应用程序中注入它应该工作,但是当我在其中一个中使用它时强>框架,我得到了绝对意想不到的结果......
wchar_t Buf[2048];
wcscpy(Buf, L"/zbxbxklbvasyfiogkhgfdbxbx/bxkfiorjhsdfohdf/xbxasdoipppwejngfd/gjfdhjgfdfdjkg.sdfsdsrtlrt.ljlg/fghlfg");
int len1 = wcslen(L"/zbxbxklbvasyfiogkhgfdbxbx/bxkfiorjhsdfohdf/xbxasdoipppwejngfd/gjfdhjgfdfdjkg.sdfsdsrtlrt.ljlg/fghlfg");
int len2 = wcslen(Buf);
char Buf2[2048];
Buf2[0]=0;
wcstombs(Buf2, Buf, 2048);
// ??? Buf2 == ""
// ??? len1 == len2 == 57, but should be 101
这怎么可能,我疯了吗?即使存在内存损坏,它也不可能破坏堆栈上分配的所有这些值...为什么即使 wcslen(L“MyWideString”)也不起作用?更改测试字符串会改变其长度,但总是错误的, wcstombs 返回-1 ...
setlocale()不在任何地方使用,测试字符串只包含 ASCII 字符,为了方便移植我使用 -fshort-wchar 编译器选项,但在测试Cocoa应用程序的情况下它可以正常工作......
请帮忙!
答案 0 :(得分:0)
C / C ++中的宽字符实现可以是任何东西,包括1个字节,2个字节或4个字节。这取决于您编译的编译器和平台。
可能维基百科不是引用的最佳地点,但在这种情况下: http://en.wikipedia.org/wiki/Wide_character表示
... wchar_t的宽度是特定于编译器的,可以小到8位。
和
...由于历史兼容性原因,宽字符应该是C90下的16位值。符合10646-1:2000 Unicode标准的C和C ++编译器通常假设32位值....
所以,不要假设并使用sizeof(wchar_t)
。
答案 1 :(得分:0)
我刚刚用GCC 4.6测试了这个。在标准设置中,这可以按预期工作,为所有长度提供101。但是,使用您的选项-fshort-wchar
我也会得到意想不到的结果(在我的情况下为51,在使用setlocale()后最终转换为251)。
所以我查看了该选项的man条目:
警告:-fshort-wchar开关导致GCC生成的代码与不使用该开关生成的代码不是二进制兼容的。使用它来符合非默认应用程序二进制接口。
我认为这解释了它:当你链接到标准库时,你应该使用正确的ABI和类型约定,你将覆盖该选项。
答案 2 :(得分:0)
-fshort-wchar
更改编译器的ABI,因此需要使用wchar_t重新编译glibc,libgcc和所有库。否则,glibc中的wcslen和其他函数仍然假设wchar_t是4个字节。