Преобразование из CFURLRef или CFStringRef в std::string

Как я могу преобразовать CFURLRef в С++ std::string?

Я также могу преобразовать CFURLRef в CFStringRef с помощью:

CFStringRef CFURLGetString ( CFURLRef anURL );

Но теперь у меня такая же проблема. Как я могу преобразовать CFStringRef в std::string?


person 3ef9g    schedule 04.03.2015    source источник


Ответы (4)


CFStringRef бесплатно подключается к объекту NSString, поэтому, если вы используете Cocoa или Objective C в любом случае, преобразование очень простое:

NSString *foo = (NSString *)yourOriginalCFStringRef;
std::string *bar = new std::string([foo UTF8String]);

Подробнее можно найти здесь.

Теперь, поскольку вы не отметили этот вопрос Cocoa или 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).

person Michael Dautermann    schedule 04.03.2015

Эта функция, возможно, является самым простым решением:

const char * CFStringGetCStringPtr ( CFStringRef theString, CFStringEncoding encoding );

Конечно, есть ctr для std::string(char*), который дает вам однострочный код для преобразования:

std::string str(CFStringGetCStringPtr(CFURLGetString(anUrl),kCFStringEncodingUTF8));
person Alan T.    schedule 03.09.2015
comment
Хотя этот ответ прост, он недавно укусил меня. Я только что обнаружил, что в документах комментарий рядом с CFStringGetCStringPtr говорит: /* May return NULL at any time; be prepared for NULL */. Так что будьте осторожны, если вы используете это. - person dgross; 30.10.2015

Самый безопасный способ добиться этого:

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

person MultiColourPixel    schedule 19.10.2016
comment
К вашему сведению: CFStringGetLength(cfString) возвращает длину для UTF-16. - person Marek R; 21.09.2018

Вот моя реализация функции преобразования

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;
}

Это еще не проверял.

person Marek R    schedule 21.09.2018