unicode和框架的难以解决的问题

时间:2011-06-14 10:26:55

标签: visual-c++ gcc unicode frameworks wchar-t

我遇到了一个非常奇怪的问题......以下简单的测试代码如果在单个 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应用程序的情况下它可以正常工作......

请帮忙!

3 个答案:

答案 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个字节。

请参阅:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42092