Получить unichar * из C ++ std :: string & amp; создать ненулевой NSString в Objective-Stack Overflow

У меня есть Objective-C ++, который оборачивает существующую библиотеку C ++. Библиотека C ++ иногда дает мне std::string& параметры, которые я хочу преобразовать в nonnull NSStrings. Почти все NSString возврат инициализаторов nullable NSStringс исключением: -initWithCharactersNoCopy:length:freeWhenDone: а также -initWithCharacters:length:, Тем не менее, оба из них требуют unichar *, но std::string.c_str() возвращается char *,

Как я могу получить unichar * из C ++ std::string так что я могу создать NSString * _Nonnull ?

Не дубликат

Другие вопросы просто хочу конвертировать из std::string в NSString, Я хочу знать, возможно ли это сделать без null NSString *возможно, вызывая методы на std::string получить unichar *, std::wstring_convert выглядит многообещающе, но я не разработчик C ++, поэтому я пока не знаю, как с этим начать.

Возможное решение

После дальнейших исследований я узнал, что std::string это просто std::basic_string<char>и кажется, что вы можете определить свой собственный std::basic_strings. Я нашел Подобный пример, который преобразуется в std::wstring:

// std::string -> std::wstring
std::string s("string");
std::wstring ws;
ws.assign(s.begin(), s.end());

Поэтому я адаптировал его к std::basic_string<unichar>и это прекрасно компилируется:

void Foo(const std::string& bar) {
std::basic_string<unichar> barUnichar;
barUnichar.assign(bar.begin(),
bar.end());
NSString * _Nonnull barNSString =
[NSString stringWithCharacters:barUnichar.c_str()
length:barUnichar.length()];
NSLog(@"bar: %@", bar);
}

Я не против, что переход от std::string в std::basic_string<unichar> выполняет ненужное копирование, и я думаю, что я могу изменить приведенный выше код для использования -[NSString initWithCharactersNoCopy:length:freeWhenDone:] как только я узнаю больше о правилах владения памятью в C ++.

Возможное решение не хорошо

Джо Грофф говорит в твиттере:

Это будет делать побайтовое отображение. Это может работать для ASCII, но
даст вам мусор для любого Unicode.

0

Решение

Давайте попробуем еще раз, посмотрим, поможет ли это вам. Вы отредактировали вопрос в ответ на предположение, что это дубликат, и добавили:

Другие вопросы просто хочу конвертировать из std::string в NSString, Я хочу знать, возможно ли это сделать без null NSString *

Прямой ответ: нет

Причина проста: библиотека Objective C не может предположить, что любой переданный ей указатель ссылается на правильно закодированную строку C, даже если этот указатель напечатан std::string,

Теперь вы можете быть очень уверены, что ваш код C ++ никогда не передаст вам неверно закодированную строку — и можно утверждать, что уверенность является разумной (но в конце концов это C ++ ;-)) — и поэтому верьте, что нулевой результат никогда не произойдет , но это не меняет того факта, что библиотека Objective C не может предположить, что не будет.

Сделай сам ответ: да

Попытка избежать нуля, например пытаясь преобразовать std::string в unichar * и т. д., как вы уже рассматривали, просто избегает этой проблемы — некоторый фрагмент кода где-то имеет дело с проверкой кодировки или с риском возврата неверно закодированного NSString,

В то время как это может быть возможно, в обоих случаях это будет более сложным делом и может привести к тому, что вы не будете знать, что возвращается за неправильные кодировки, по сравнению с подходом «сделай сам»: просто разберитесь с нулем, верните себя в источнике и замените его чем-то другим. Например:

std::string someCstring;

NSString *convertedString = @(someCstring.c_str()) ?: @"ERROR: C string is invalid UTF8";

Вот convertedString никогда не будет nil,

(Если ваша строка C не UTF8, вам нужно будет использовать другую NSString инициализатор, который принимает кодировку.)

НТН

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]