Swift - 从UnsafePointer <uint8>转换为String </uint8>

时间:2014-07-30 16:59:50

标签: swift type-conversion

我考虑了很多类似的问题,但仍然无法让编译器接受这个问题。

Socket Mobile API(在Objective-C中)将ISktScanDecodedData传递给Swift中的委托方法(数据可能是二进制的,我想这就是为什么它不是以字符串形式提供的):

func onDecodedData(device: DeviceInfo?, DecodedData d: ISktScanDecodedData?) {
  let symbology: String = d!.Name()
  let rawData: UnsafePointer<UInt8> = d!.getData()
  let rawDataSize: UInt32 = decoded!.getDataSize()
  // want a String (UTF8 is OK) or Swifty byte array...
}

在C#中,此代码将原始数据转换为字符串:

string s = Marshal.PtrToStringAuto(d.GetData(), d.GetDataSize());

在Swift中,我可以达到UnsafeArray,但后来我被卡住了:

let rawArray = UnsafeArray<UInt8>(start: rawData, length: Int(rawDataSize))

或者,我看到String.fromCStringNSString.stringWithCharacters,但两者都不会接受手头的参数类型。例如,如果我可以从UnsafePointer<UInt8>转换为UnsafePointer<()>,那么这将是可用的(尽管我不确定它是否安全):

NSData(bytesNoCopy: UnsafePointer<()>, length: Int, freeWhenDone: Bool)

是否有明显的方法可以从所有这些中获取字符串?

2 个答案:

答案 0 :(得分:15)

这个怎么样,&#39;纯粹&#39; Swift 2.2而不是使用NSData:

public extension String {

  static func fromCString
    (cs: UnsafePointer<CChar>, length: Int!) -> String?
  {
    if length == .None { // no length given, use \0 standard variant
      return String.fromCString(cs)
    }

    let buflen = length + 1
    var buf    = UnsafeMutablePointer<CChar>.alloc(buflen)
    memcpy(buf, cs, length))
    buf[length] = 0 // zero terminate
    let s = String.fromCString(buf)
    buf.dealloc(buflen)
    return s
  }
}

和Swift 3:

public extension String {

  static func fromCString
    (cs: UnsafePointer<CChar>, length: Int!) -> String?
  {
    if length == nil { // no length given, use \0 standard variant
      return String(cString: cs)
    }

    let buflen = length + 1
    let buf    = UnsafeMutablePointer<CChar>.allocate(capacity: buflen)
    memcpy(buf, cs, length)
    buf[length] = 0 // zero terminate
    let s = String(cString: buf)
    buf.deallocate(capacity: buflen)
    return s
  }
}

不可否认,分配缓冲区并复制数据只是为了添加零终结符有点愚蠢。

显然,正如Zaph所说,你需要确保你对字符串编码的假设是正确的。

答案 1 :(得分:10)

这应该有效:

let data = NSData(bytes: rawData, length: Int(rawDataSize))
let str = String(data: data, encoding: NSUTF8StringEncoding)

Swift 3的更新:

let data = Data(bytes: rawData, count: Int(rawDataSize))
let str = String(data: data, encoding: String.Encoding.utf8)

如果数据不代表,结果字符串为nil 一个有效的UTF-8序列。