Преобразовать из CFURLRef или CFStringRef в std::string
Как я могу конвертировать CFURLRef
на C++ std::string
?
Я также могу конвертировать из CFURLRef
к CFStringRef
от:
CFStringRef CFURLGetString ( CFURLRef anURL );
Но сейчас у меня такая же проблема. Как я могу конвертировать CFStringRef
к std::string
?
4 ответа
CFStringRef - это бесплатный мост, соединенный с объектом NSString, поэтому, если вы используете Какао или Objective C, преобразование очень просто:
NSString *foo = (NSString *)yourOriginalCFStringRef;
std::string *bar = new std::string([foo UTF8String]);
Более подробную информацию можно найти здесь.
Теперь, так как вы не пометили этот вопрос Какао или Objective-C, я предполагаю, что вы не хотите использовать решение Objective-C.
В этом случае вам нужно получить строковый эквивалент C из вашего CFStringRef:
const CFIndex kCStringSize = 128;
char temporaryCString[kCStringSize];
bzero(temporaryCString,kCStringSize);
CFStringGetCString(yourStringRef, temporaryCString, kCStringSize, kCFStringEncodingUTF8);
std::string *bar = new std::string(temporaryCString);
Я не делал никаких проверок ошибок в этом коде, и вам может понадобиться завершить строку, извлеченную через CFStringGetCString
(Я пытался смягчить это, делая bzero
).
Эта функция, возможно, самое простое решение:
const char * CFStringGetCStringPtr ( CFStringRef theString, CFStringEncoding encoding );
Конечно, есть ctr для std::string(char*), который дает вам одну строчку для преобразования:
std::string str(CFStringGetCStringPtr(CFURLGetString(anUrl),kCFStringEncodingUTF8));
Самый безопасный способ достижения этого будет:
CFIndex bufferSize = CFStringGetLength(cfString) + 1; // The +1 is for having space for the string to be NUL terminated
char buffer[bufferSize];
// CFStringGetCString is documented to return a false if the buffer is too small
// (which shouldn't happen in this example) or if the conversion generally fails
if (CFStringGetCString(cfString, buffer, bufferSize, kCFStringEncodingUTF8))
{
std::string cppString (buffer);
}
CFStringGetCString
не задокументировано возвращать NULL как CFStringGetCStringPtr
Можно.
Убедитесь, что вы используете правильный CFStringEncoding
тип. Я думаю, что кодировка UTF8 должна быть безопасной для большинства вещей.
Вы можете проверить документацию Apple о CFStringGetCString
по адресу https://developer.apple.com/reference/corefoundation/1542721-cfstringgetcstring?language=objc
Вот моя реализация функции преобразования
std::string stdStringFromCF(CFStringRef s)
{
if (auto fastCString = CFStringGetCStringPtr(s, kCFStringEncodingUTF8))
{
return std::string(fastCString);
}
auto utf16length = CFStringGetLength(s);
auto maxUtf8len = CFStringGetMaximumSizeForEncoding(utf16length, kCFStringEncodingUTF8);
std::string converted(maxUtf8len, '\0');
CFStringGetCString(s, converted.data(), maxUtf8len, kCFStringEncodingUTF8);
converted.resize(std::strlen(converted.data()));
return converted;
}
Еще не проверял.