2017-08-22 50 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

相关问题