길이가 있는 안전하지 않은 포인터를 Swift Array 유형으로 변환
저는 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)
, 그러나 그렇다고 해서 루프 자체의 문제가 제거되는 것은 아닙니다.
변환 방법에 대한 SO 질문에 대해 알고 있습니다.UnsafePointer<Int8>
로.String
,하지만String
완전히 다른 짐승입니다.[T]
. a에서 swift 길이 바이트를 복사하는 편리한 방법이 있습니까?UnsafePointer<T>
로[T]
? 저는 통과하지 않고 순수한 스위프트 방식을 선호합니다.NSData
또는 유사한.만약 위의 알고리즘이 정말로 유일한 방법이라면, 저는 기꺼이 그것을 고수할 것입니다.
간단히 스위프트를 초기화할 수 있습니다.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
포인터가 가리키는 항목 수입니다.
만약 당신이.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는 바이트 수입니다.예:
let arr = convert(12, data: ptr, Float.self)
3개의 배열을 만들 겁니다Float
s가 가리키는 12바이트에서 sptr
.
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
}
}
행 데이터를 바이트(Uint8)로 변환할 수 있습니다.
확장명 복사 후 사용..
Array init 기능을 사용할 수도 있습니다.
init(unsafeUninitializedCapacity: Int, initializingWith initializer: (inout UnsafeMutableBufferPointer<Element>, inout Int) throws -> Void) rethrows
먼저 필요한 경우 안전하지 않은 RawPointer를 안전하지 않은 포인터로 변환한 다음 포인터를 버퍼 포인터로 변환하고 마지막으로 버퍼 포인터를 배열로 변환합니다.
예제, 안전하지 않은 RawPoint가 있다고 가정(dataPtr
) 및 크기(dataSize
)
let numberOfItems = dataSize / MemoryLayout<MyClass>.stride
let myArray = dataPtr.withMemoryRebound(to: MyClass.self,
capacity: numberOfItems) { typedPtr in
// Convert pointer to buffer pointer to access buffer via indices
let bufferPointer = UnsafeBufferPointer(start: typedPtr, count: numberOfItems)
// Construct array
return [MyClass](unsafeUninitializedCapacity: numberOfItems) { arrayBuffer, count in
count = numberOfItems
for i in 0..<count {
arrayBuffer[i] = bufferPointer[i]
}
}
}
언급URL : https://stackoverflow.com/questions/32606989/converting-an-unsafepointer-with-length-to-a-swift-array-type
'programing' 카테고리의 다른 글
Oracle의 PERCENTILE_CONT 함수의 PostgreSQL 등가물 (0) | 2023.09.26 |
---|---|
MySQL 쿼리 캐싱을 비활성화하는 방법 (0) | 2023.09.26 |
이벤트 핸들러 이전에 jQuery에서 ajax 응답을 가로채려면 어떻게 해야 합니까? (0) | 2023.09.26 |
javax.xml.bind.모듈 경로 또는 클래스 경로에서 JAXB-API의 JAXB 예외 구현을 찾을 수 없습니다. (0) | 2023.09.26 |
사각형 괄호를 사용하여 Pandas 열에 액세스 vs 점(속성 같은) 사용 (0) | 2023.09.26 |