【问题标题】:Convert from CFURLRef or CFStringRef to std::string从 CFURLRef 或 CFStringRef 转换为 std::string
【发布时间】:2015-03-04 16:43:37
【问题描述】:

如何将 CFURLRef 转换为 C++ std::string

我还可以通过以下方式将CFURLRef 转换为CFStringRef

CFStringRef CFURLGetString ( CFURLRef anURL );

但现在我遇到了同样的问题。如何将CFStringRef 转换为std::string

【问题讨论】:

    标签: c++ macos stdstring cfstring cfurl-encoding


    【解决方案1】:

    CFStringRef is toll free bridged 到 NSString 对象,所以如果你以任何方式使用 Cocoa 或 Objective C,转换非常简单:

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

    更多详情can be found here

    现在,由于您没有使用 Cocoa 或 Objective-C 标记此问题,我猜您不想使用 Objective-C 解决方案。

    在这种情况下,您需要从 CFStringRef 中获取 C 字符串等价物:

    const CFIndex kCStringSize = 128; 
    char temporaryCString[kCStringSize];
    bzero(temporaryCString,kCStringSize);
    CFStringGetCString(yourStringRef, temporaryCString, kCStringSize, kCFStringEncodingUTF8);
    std::string *bar = new std::string(temporaryCString);
    

    我没有对此代码进行任何错误检查,您可能需要空终止通过CFStringGetCString 获取的字符串(我尝试通过执行bzero 来缓解这种情况)。

    【讨论】:

      【解决方案2】:

      这个函数可能是最简单的解决方案:

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

      当然,std::string(char*) 有一个 ctr,它为您提供了这一单行转换:

      std::string str(CFStringGetCStringPtr(CFURLGetString(anUrl),kCFStringEncodingUTF8));
      

      【讨论】:

      • 虽然这个答案很简单,但它最近让我很生气。我刚刚发现在文档中,CFStringGetCStringPtr 旁边的评论说:/* May return NULL at any time; be prepared for NULL */。因此,如果您使用它,请小心。
      【解决方案3】:

      实现这一目标的最安全方法是:

      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 编码对于大多数事情来说应该是安全的。

      你可以在https://developer.apple.com/reference/corefoundation/1542721-cfstringgetcstring?language=objc查看苹果关于CFStringGetCString的文档

      【讨论】:

      • 仅供参考:CFStringGetLength(cfString) 返回 UTF-16 的长度。
      【解决方案4】:

      这是我实现的转换函数

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

      还没有测试。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-28
        相关资源
        最近更新 更多