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

问题描述 投票:0回答:4

简短版我正在使用unicode。我试图将std :: string用于需要const 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.\0"; 
AddString(wcBuff, wcslen(wcBuff), &gFontFamilyInfo, FontStyleBold, 20, ptOrg_Controls, &strFormat_Info);

现在这就是我一直在努力的,一整天和旁注:我的转换功能工作正常,不是问题,也不是创建问题。

// problems
string s = "Level " + convert::intToString(6) + "\0"; 

// 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();

一切都在编译,但随后出现问题。一旦达到该点,就会出现一些运行时错误。其他人访问违规和段错误。有些编译和调试没有问题,但字符串输出随着随机字符不断变化。

有任何想法吗?

c++ gdi+
4个回答
0
投票

(这不是一个真正的答案,但它对评论来说太大了)

尝试1:你没有空终止字符串

尝试2:没有看到转换功能就无法评论。删除演员阵容。

尝试3:删除演员阵容,应该没问题。

在所有情况下使用wchar_t const *wcBuff。如果“尝试3”失败,则表示您的代码中的其他位置存在错误,该错误会显示在此处。尝试生产MCVE。你应该可以将它降低到大约10-20行。

即使你设法为你想要的东西编写正确的代码,这也是一个相当天真的转换,因为它不能正确处理0-127范围之外的字符。您需要考虑这是否是您想要的,或者您是否想要进行UTF-8转换等。

在Windows中,您可以使用MultiByteToWideChar


0
投票
#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;
}

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 + Command中使用它,如下所示:

graphics.DrawString(str1.c_str(), -1,
    &font, PointF(10, 5), &st);

-1
投票

首先是第一件事。 GDI+是一个C ++库。它使用Microsoft C ++ ABI。 Microsoft C ++ ABI与gcc非常不兼容,因此您可能会忘记使用它。您可以尝试使用WinAPI或任何其他使用C调用约定的库。

现在为wstring问题。 wchar_t在gcc中是32位宽,但Windows API要求它是16位宽。您不能使用任何需要wchar_t的本机Windows调用。

您可以在-fshort-wchar中使用gcc命令行选项,这将使wchar_t 16位宽,您将重新获得与Windows API的兼容性,但失去与libc的兼容性,因此没有为您执行wchar_t的库函数。 std::wstring可能会工作,因为它只是标题,但wprintfwscpy或所有其他编译的东西不会。

这些都不是在编译时检测到的,因为gcc看到的唯一内容是头文件。它无法判断相应的库是使用16位wchar_t还是32位wchar_t编译的。

当您需要将uint16_t数组传递给Windows函数时,可以使用wchar_t。如果你可以使用C ++ 11,它也有你可以使用的char16_t。这是一个应该与Basic Multilingual Plane角色一起使用的示例:

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-ish API,就可以使用gcc。

© www.soinside.com 2019 - 2024. All rights reserved.