将std::string转换为GDI+参数所需的const WCHAR*字符串



短版本我使用的是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可能只作为它的头工作,但wprintfwscpy或所有其他编译的东西不会。

这些在编译时都没有检测到,因为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。

最新更新