短版本我使用的是unicode。我正试图将std::字符串用于一个需要常量WCHAR字符串的函数;DrawString(const WCHAR,…
我用GCC编译。一切都是unicode,我已经指定了。
我一直在尝试将一个字符串转换为wchar_t*。目的是让我可以使用GDI+函数输出,它的参数需要它。
以下是我如何输出字符串文字,没有问题,调试良好,工作良好。http://msdn.microsoft.com/en-us/library/ms535991%28v=vs.85%29.aspx参考原因:
// works fine
wchar_t* wcBuff;
wcBuff = (wchar_t*)L"Some text here. ";
AddString(wcBuff, wcslen(wcBuff), &gFontFamilyInfo, FontStyleBold, 20, ptOrg_Controls, &strFormat_Info);
这是我一整天都在尝试的,还有一点要注意:我的转换函数工作得很好,这不是问题,也不是创建问题。
// problems
string s = "Level " + convert::intToString(6) + " ";
// try 1 - Segfault
wchar_t* wcBuff = new wchar_t[s.length() + 1];
copy(s.begin(), s.end(), wcBuff);
// random tries, compiles, but access violations (my conversion function here has worked other places, do not know for sure here.
wchar_t* wcBuff;
wstring wstr = convert::stringToWideChar(s);
wstring strvalue = convert::stringToWideChar(s);
wcBuff = (wchar_t*)strvalue.c_str();
wcBuff = (wchar_t*)wstr.c_str();
wstring foo;
foo.assign(s.begin(), s.end());
wcBuff = (wchar_t*)foo.c_str();
一切都会编译,但随后会出现问题。一旦达到该点,就会出现一些运行时错误。其他人访问违规和segfault。有些编译和调试没有问题,但字符串输出会随着随机字符不断变化。
有什么想法吗?
(这不是一个真正的答案,但它太大了,无法发表评论)
尝试1:你没有空终止字符串
尝试2:在没有看到转换函数的情况下无法进行评论。拆下铸件。
尝试3:移除投射,应该没问题。
在所有情况下都使用wchar_t const *wcBuff
。如果"Try 3"失败,那么这意味着你的代码中有一个错误,它显示在这里。尝试生成MCVE。你应该能够把它降到大约10-20行。
即使您设法为您想要的内容编写了正确的代码,这也是一个相当天真的转换,因为它不能正确处理0-127范围之外的字符。你需要考虑这是否是你想要的,或者你是否想进行UTF-8转换,等等。
在Windows中,您可以使用MultiByteToWideChar。
#include <string>
int main() {
// Can use convenient wstring
std::wstring wstr = L"My wide string";
// When you need a whar_t* just do this
const wchar_t* s = wstr.c_str();
// unicode form of strcpy
wchar_t buf[100] = {0};
wcscpy (buf,s);
// And if you want to convert from string to wstring
std::string thin = "I only take up one byte per character!";
std::wstring wide(thin.begin(), thin.end());
return 0;
}
我首先将数据放入一个wstring中。像这样:
(从字符串转换):
std::string sString = "This is my string text";
std::wstring str1(sString.begin(), sString.end());
(从int转换):
wstring str1 = std::to_wstring(BirthDate);
然后,我在GDI+命令中使用它,如下所示:
graphics.DrawString(str1.c_str(), -1,
&font, PointF(10, 5), &st);
第一件事。CCD_ 2是一个C++库。它使用Microsoft C++ABI。Microsoft C++ABI与gcc
极不兼容,因此您可能会忘记使用它。您可以尝试使用WinAPI或任何其他使用C调用约定的库。
现在是wstring
问题。wchar_t
在gcc中是32位宽,但Windows API要求它是16位宽。不能使用任何需要wchar_t
的本机Windows调用。
您可以在gcc
中使用-fshort-wchar
命令行选项,这将使wchar_t
具有16位宽,您将重新获得与Windows API的兼容性,但失去与libc
的兼容性,因此没有对wchar_t
起作用的库函数。std::wstring
可能只作为它的头工作,但wprintf
或wscpy
或所有其他编译的东西不会。
这些在编译时都没有检测到,因为gcc
只能看到头文件。它无法判断对应的库是用16位wchar_t
编译的还是用32位wchar_t
编译的。
当需要将wchar_t
的数组传递给Windows函数时,可以使用uint16_t
。如果你能使用C++11,它也有GDI+
0可以使用。下面是一个应该使用基本多语言平面字符的示例:
std::wstring myLittleNiceWstring;
...
std::vector<uint16_t> myUglyCompatibilityString;
std::copy(myLittleNiceWstring.begin(),
myLittleNiceWstring.end(),
std::back_inserter(myUglyCompatibilityString));
myUglyCompatibilityString.push_back(0);
UglyWindowsAPI(static_cast<WCHAR*>(myUglyCompatibilityString.data());
如果您有非BMP字符,则需要将UTF32转换为UTF16,而不仅仅是使用std::copy复制字符。您可以使用libiconv
来实现这一点,也可以自己编写转换例程(这很简单),也可以从互联网上下载一些代码。
我认为,由于这个和其他问题,使用GCC进行以Windows为中心的开发相当困难。只要坚持使用POSIX-ishAPI,就可以使用gcc。