且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在SWIFT中使用C ++ FFT代码

更新时间:2023-02-26 20:17:35

如果您想从Swift调用该C ++代码,则需要通过Objective-C ++进行桥接.在SO上的简单搜索将显示许多有关如何执行此操作的帖子.

If you would like to invoke that C++ code from Swift, you will need to bridge via Objective-C++. A simple search here on SO will reveal numerous posts on how to do that.

在这种情况下,我们希望在将C ++/Objective-C ++/Swift粘合在一起时,尽量减少数据复制,以减少对性能的负面影响. Swift中Double中的ArrayArray将其数据存储在连续存储中,因为Double不是类. ArraywithUnsafeMutableBufferPointer方法似乎是解决方案的有希望的选择.不过,我会小心一点,首先在一个简单的测试程序上测试这种方法.在时间允许的情况下,我将在接下来的几天中尝试一些解决方案.

In this case we would want to minimize copying of the data as we glue C++/Objective-C++/Swift together in order to reduce negatively affecting performance. Array of Doubles in Swift stores its data in contiguous storage, as Double is not a class. The withUnsafeMutableBufferPointer method of Array appears to be a promising option for a solution. I would be careful, though, and test this approach on a simple test program first. I'll try to come up with something in the next few days, time permitting.

请在 https://developer.apple.com/documentation上查看Array的文档./swift/array .另一个非常有用的资源是 https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/index.html#//apple_ref/doc/uid/TP40014216-CH2-ID0 ,您可能已经在搜索此主题时见过.

Please see documentation for Array at https://developer.apple.com/documentation/swift/array. Another very useful resource is https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/index.html#//apple_ref/doc/uid/TP40014216-CH2-ID0, which you may have already seen searching this topic.

通常要注意的一件事是,例如,如果调整向量的大小,则可以将C ++中的vector存储空间重新放置在内存中,在这种情况下,当从Swift桥接到C ++.但是,此C ++代码似乎没有做任何会移动基础存储的事情.

One thing to be careful about in general is that vector storage in C++ can be relocated in memory if vector is resized, for example, in which case we would have to make extra copies of the data when bridging from Swift to C++. However, this C++ code doesn't seem to do anything that would move the underlying storage.

2017年10月25日更新:使用withUnsafeMutableBufferPointer将需要在内存中复制数组,因为创建直接直接使用给定缓冲区的vector存在问题.请参阅如何廉价地将C样式数组分配给std :: vector ?.

Update 10/25/2017: Using withUnsafeMutableBufferPointer will require copying arrays in memory because it is problematic to create a vector that directly, in-place, uses a given buffer. See How to cheaply assign C-style array to std::vector?.

但是,由于库的C版本可用,因此这简直是小菜一碟:

However, since there is a C version of the library available, this becomes a piece of cake:

  • fft.hfft.c添加到您的Xcode项目中.
  • 在桥接头中导入fft.h.
  • Add fft.h and fft.c to your Xcode project.
  • Import fft.h in your bridging header.

然后您可以像下面这样在Swift中使用C代码:

Then you can use the C code in Swift like this:

var dReal : [Double] = [1,2,-3,4]
var dImg : [Double] = [-4,3,2,1]

dReal.withUnsafeMutableBufferPointer { (real : inout UnsafeMutableBufferPointer<Double> ) in
    dImg.withUnsafeMutableBufferPointer { (img : inout UnsafeMutableBufferPointer<Double>) in
        if (real.count == img.count) {
            Fft_transform(real.baseAddress, img.baseAddress, real.count)
        }
    }
}

当然,这只是一个简单的例子.您可以使其更高级,添加错误处理等.

Of course, this is just a bare-bones example. You can make it fancier, add error handling etc.