我考虑了很多类似的问题,但仍然无法让编译器接受这个问题。
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.fromCString
和NSString.stringWithCharacters
,但两者都不会接受手头的参数类型。例如,如果我可以从UnsafePointer<UInt8>
转换为UnsafePointer<()>
,那么这将是可用的(尽管我不确定它是否安全):
NSData(bytesNoCopy: UnsafePointer<()>, length: Int, freeWhenDone: Bool)
是否有明显的方法可以从所有这些中获取字符串?
答案 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序列。