私はSwiftで合理的なCの相互運用性を達成するための最も簡単な方法を探しています、そして私の現在のブロックは_UnsafePointer<Int8>
_(これは_const char *
_)を_[Int8]
_配列に変換しています。
現在、私はUnsafePointer
とバイト数を取得し、それを要素ごとに配列に変換できる単純なアルゴリズムを持っています。
_func convert(length: Int, data: UnsafePointer<Int8>) {
let buffer = UnsafeBufferPointer(start: data, count: length);
var arr: [Int8] = [Int8]()
for (var i = 0; i < length; i++) {
arr.append(buffer[i])
}
}
_
ループ自体はarr.reserveCapacity(length)
を使用して高速化できますが、ループ自体の問題は取り除かれません。
this SO question を知っています。これは_UnsafePointer<Int8>
_をString
に変換する方法をカバーしますが、String
は_[T]
_とは完全に異なる獣。便利なSwift長さバイトを_UnsafePointer<T>
_から_[T]
_にコピーする方法はありますか?純粋な= Swiftメソッド、NSData
などを経由せずに。上記のアルゴリズムが本当にそれを行う唯一の方法である場合、私はそれを固く満足しています。
単純にSwift Array
をUnsafeBufferPointer
から初期化できます:
func convert(length: Int, data: UnsafePointer<Int8>) -> [Int8] {
let buffer = UnsafeBufferPointer(start: data, count: length);
return Array(buffer)
}
これにより、必要なサイズの配列が作成され、データがコピーされます。
または、汎用関数として:
func convert<T>(count: Int, data: UnsafePointer<T>) -> [T] {
let buffer = UnsafeBufferPointer(start: data, count: count);
return Array(buffer)
}
ここで、length
は、ポインターが指すitemsの数です。
UInt8
ポインターはあるが、ポイント先のデータから[T]
配列を作成したい場合、これは可能な解決策です。
// Swift 2:
func convert<T>(length: Int, data: UnsafePointer<UInt8>, _: T.Type) -> [T] {
let buffer = UnsafeBufferPointer<T>(start: UnsafePointer(data), count: length/strideof(T));
return Array(buffer)
}
// Swift 3:
func convert<T>(length: Int, data: UnsafePointer<UInt8>, _: T.Type) -> [T] {
let numItems = length/MemoryLayout<T>.stride
let buffer = data.withMemoryRebound(to: T.self, capacity: numItems) {
UnsafeBufferPointer(start: $0, count: numItems)
}
return Array(buffer)
}
ここで、length
nowはbytesの数です。例:
let arr = convert(12, data: ptr, Float.self)
Float
が指す12バイトから3つのptr
sの配列を作成します。
extension NSData {
public func convertToBytes() -> [UInt8] {
let count = self.length / sizeof(UInt8)
var bytesArray = [UInt8](count: count, repeatedValue: 0)
self.getBytes(&bytesArray, length:count * sizeof(UInt8))
return bytesArray
}
}
行データをbytsに変換できます(Uint8)
拡張機能をコピーして使用します。