Вам необходимо избегать использования AnsiString
в качестве двоичного буфера в Delphi/C++ Builder 2009 и более поздних версиях. Это кодированная строка, и это может привести к получению тонких/неожиданных преобразований данных из одной кодовой страницы в другую по мере прохождения строки. В вашем случае ???
является прямым результатом данных, фактически преобразованных в кодовую страницу Ansi, которая не поддерживает символы Unicode, которые вы пытаетесь использовать.
Вы действительно должны использовать TBytes
для двоичных данных. Для UTF-8 закодированной строки, используйте UTF8String
вместо:
String temp = L"汉语/漢語";
UTF8String raw = UTF8String(temp);
...
String dest = String(raw);
С учетом сказанного, так как вы должны Interop с 3-сторонней библиотеки, ожидающий UTF-8 кодируются AnsiString
как двоичный буфер , то вы можете по крайней мере использовать UTF8String
переменной и тип-брось (не назначать его), чтобы AnsiString
при прохождении его в библиотеку:
library_function(*(reinterpret_cast<AnsiString*>(&raw));
Или:
library_function(reinterpret_cast<AnsiString&>(raw));
Это работает, потому что AnsiString
, UTF8String
и RawByteString
все они основаны на том же типе AnsiStringT
основания:
typedef AnsiStringT<0> AnsiString;
typedef AnsiStringT<65001> UTF8String;
typedef AnsiStringT<65535> RawByteString;
и таким образом все разделяют общий макет памяти и реализации под капотом, и Delphi будет принимать это просто хорошо.
Если вы хотите быть действительно приключений, вы должны обновить библиотеку, чтобы использовать RawByteString
или UTF8String
(если не TBytes
) вместо AnsiString
, то вам не нужен тип-бросок на всех :
library_function(raw);
: вам действительно нужно получить новую версию этой библиотеки или использовать другую библиотеку.
: Это тип ситуации, изначально предназначавшийся для RawByteString
.Он никогда не предназначался для использования для автономных переменных, но для параметров функций, которые могут принимать любой тип 8-битовой строки в качестве входных данных без выполнения преобразования данных.
Что вы делаете неправильно, используется 'AnsiString'. Вам нужно прекратить это делать. Вам нужно хранить данные в кодировке Unicode. ANSI не выполнит свою работу. Либо UTF-16, либо UTF-8, но не ANSI. Без какого-либо знания устаревших мотивов трудно сказать вам решение. –
Я знаю это, но проблема в том, что в старой библиотеке AnsiString используется для хранения двоичных данных, в данном случае UTF8. Мне нужно будет переписать всю библиотеку, поэтому я пытаюсь использовать ее без критических изменений. Я думал, что могу продолжать использовать AnsiString для хранения двоичных данных без преобразования страницы. Разве это невозможно? – kokokok
Я не знаю достаточно о эмуляции C++ Builder строк Delphi, но в Delphi я бы использовал 'UTF8String' для кодированного текста UTF-8 и' TBytes' для двоичных данных. Я бы потратил время на реорганизацию этого. Обратите внимание, что (по крайней мере, в Delphi) вы можете напрямую конвертировать между 'UTF8String' и' UnicodeString' без каких-либо потерь. –