1

.NETからのUnicode文字列をネイティブC++に変換して、テキストファイルに書き込もうとしています。次に、プロセスを逆にして、ファイルのテキストを読み取り、管理対象のUnicode文字列に変換します。

私は次のコードを使用します:

String^ FromNativeToDotNet(std::string value)
{
  // Convert an ASCII string to a Unicode String
  std::wstring wstrTo;
  wchar_t *wszTo = new wchar_t[lvalue.length() + 1];
  wszTo[lvalue.size()] = L'\0';
  MultiByteToWideChar(CP_UTF8, 0, value.c_str(), -1, wszTo, (int)value.length());
  wstrTo = wszTo;
  delete[] wszTo;

  return gcnew String(wstrTo.c_str());
}


std::string FromDotNetToNative(String^ value)
{ 
  // Pass on changes to native part
  pin_ptr<const wchar_t> wcValue = SafePtrToStringChars(value);
  std::wstring wsValue( wcValue );

  // Convert a Unicode string to an ASCII string
  std::string strTo;
  char *szTo = new char[wsValue.length() + 1];
  szTo[wsValue.size()] = '\0';
  WideCharToMultiByte(CP_UTF8, 0, wsValue.c_str(), -1, szTo, (int)wsValue.length(), NULL, NULL);
  strTo = szTo;
  delete[] szTo;

  return strTo;
}

たとえば、日本語の文字が2つのASCII文字に変換されるとどうなりますか(漢-> "w)。それは正しいと思いますか?しかし、他の方法は機能しません。FromNativeToDotNetwizh" wを呼び出すと、管理対象として"wのみが取得されます。 unicode文字列...日本語の文字を正しく復元するにはどうすればよいですか?

4

3 に答える 3

3

UTF8Encodingを使用するのに最適です:

static String^ FromNativeToDotNet(std::string value)
{
    array<Byte>^ bytes = gcnew array<Byte>(value.length());
    System::Runtime::InteropServices::Marshal::Copy(IntPtr((void*)value.c_str()), bytes, 0, value.length());
    return (gcnew System::Text::UTF8Encoding)->GetString(bytes);
}


static std::string FromDotNetToNative(String^ value)
{ 
    if (value->Length == 0) return std::string("");
    array<Byte>^ bytes = (gcnew System::Text::UTF8Encoding)->GetBytes(value);
    pin_ptr<Byte> chars = &bytes[0];
    return std::string((char*)chars, bytes->Length);
}
于 2012-05-24T03:16:50.080 に答える
2

日本語の文字は 2 つの ASCII 文字 (漢 -> "w") に変換されます。それは正しいと思いますか?

いいえ、その文字 U+6F22 は 3 バイトに変換する必要があります: 0xE6 0xBC 0xA2

UTF-16 (リトル エンディアン) では、U+6F22 は 0x22 0x6F としてメモリに格納され"oます"w

String^ から std::wstring に変換する正しい方法を知るには、String^ に精通していませんが、それが問題の原因であると確信しています。


以下はあなたの問題とは何の関係もないと思いますが、明らかに間違っています:

std::string strTo;
char *szTo = new char[wsValue.length() + 1];

1 つのワイド文字が複数のナロー文字を生成できることはすでにわかっているため、ワイド文字の数は対応するナロー文字の数以上であるとは限りません。

WideCharToMultiByte を使用してバッファー サイズを計算し、そのサイズのバッファーで再度呼び出す必要があります。または、ワイド文字の 3 倍の文字数を保持するバッファを割り当てることもできます。

于 2012-05-23T15:55:59.577 に答える
1

代わりにこれを試してください:

String^ FromNativeToDotNet(std::string value)
{
  // Convert a UTF-8 string to a UTF-16 String
  int len = MultiByteToWideChar(CP_UTF8, 0, value.c_str(), value.length(), NULL, 0);
  if (len > 0)
  {
    std::vector<wchar_t> wszTo(len);
    MultiByteToWideChar(CP_UTF8, 0, value.c_str(), value.length(), &wszTo[0], len);
    return gcnew String(&wszTo[0], 0, len);
  }

  return gcnew String((wchar_t*)NULL);
}

std::string FromDotNetToNative(String^ value)
{ 
  // Pass on changes to native part
  pin_ptr<const wchar_t> wcValue = SafePtrToStringChars(value);

  // Convert a UTF-16 string to a UTF-8 string
  int len = WideCharToMultiByte(CP_UTF8, 0, wcValue, str->Length, NULL, 0, NULL, NULL);
  if (len > 0)
  {
    std::vector<char> szTo(len);
    WideCharToMultiByte(CP_UTF8, 0, wcValue, str->Length, &szTo[0], len, NULL, NULL);
    return std::string(&szTo[0], len);
  }

  return std::string();
}
于 2012-05-24T01:21:27.327 に答える