Преобразовать из 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;
}

Еще не проверял.

Другие вопросы по тегам