2017-08-22 52 views
1

我有一個C++函數(包裹在OBJ-C文件在Xcode):將幀緩衝區從Swift傳遞到C++的正確方法是什麼?

int64_t* findEdges(int64_t* pixels, int width, int height); 

,我想從夫特3調用,並通過在一個完整的畫面數據的緩衝器。狩獵周圍後我與調用它:

var ptr = (NSData(data: imageRep.tiffRepresentation!).bytes).bindMemory(to: Int64.self, capacity: 4 * height * width).pointee 

let processor = findEdges(&ptr, width, height) 

但訪問大約30點或40的地址在C++文件後,我收到了EXC_BAD_ACCESS崩潰。

問題是我從Swift傳遞不安全的指針?什麼是正確的呼叫程序?

回答

1

這裏至少有一些這種方法的問題。可能還有更多,因爲我不知道findEdges()輸入意味着什麼以及該函數如何找到邊緣。

  1. NSDatabytes屬性不綁定到任何類型的原始指針。對bindMemory的調用然後指示NSData的內容將被看作是8字節整數的4 * height * width的緩衝區,即32 * height * width字節的緩衝區。我最近沒有使用TIFF格式,但我強烈懷疑大小爲width x height的圖像的TIFF表示將包含比此更少的字節,因此即使緩衝區已成功傳遞到findEdges,也試圖將其視爲比它大得多會導致訪問違規。

  2. 的前8個字節圖像的TIFF表示的被視爲一個Int64複製ptr變量,它的地址然後被傳遞給findEdges,這將其視爲的4 * height * widthInt64一個緩衝區的地址值。但是,緩衝區中只有第一個Int64與圖像有關(它包含TIFF表示的前8個字節)。當findEdges訪問pixels陣列中的第二個Int64時,它將訪問與圖像無關的內存。訪問一些(垃圾)Int64值可能是幸運的,但最終會嘗試訪問它不能的東西。

解決方案依賴於findEdges需要pixels是否包含完全相同的字節序列圖像的TIFF表示,或需要進行一些改造。換句話說,我們可以說TIFF表示的前8個字節組成第一個元素,即第二個8字節 - 第二個元素等。這是一個簡單的簡單例子,您可以根據自己的需要進行調整。比方說,C++函數需要的short秒的陣列,它的大小,看起來像這樣:

void processBuffer(int16_t * buf, int count) { 
... 
} 

我們想從斯威夫特傳遞Data的內容作爲緩衝。這裏是一個可以如何去這樣做:

var myData = ... 
myData.withUnsafeMutableBytes({(p: UnsafeMutablePointer<Int16>) -> Void in 
    processBuffer(p, Int32(myData.count/2)) 
}) 

請注意,該緩衝區可以進行修改,而不僅僅是閱讀,但在C++代碼,並且這些變化將在myData反映。

+0

感謝您的詳細解答。我會看看你的建議。 – Todd

+0

祕密是學習'.withUnsafeMutableBytes' – Todd

相關問題