如何将数组从 Swift 传递到 MSL 参数(C++)

Posted

技术标签:

【中文标题】如何将数组从 Swift 传递到 MSL 参数(C++)【英文标题】:How do I pass an array from Swift to MSL parameter (C++) 【发布时间】:2021-11-06 05:37:30 【问题描述】:

我想做这个自定义 CIFilter。

var dummyColors = [
        CIVector(x: 0.9, y: 0.3, z: 0.4),
        CIVector(x: 0.2, y: 0.5, z: 0.9),
        CIVector(x: 0.5, y: 0.9, z: 0.3)
    ]
    
    var normal = dummyColors.withUnsafeMutableBufferPointer  (buffer) -> UnsafeMutablePointer<CIVector> in
        var p = buffer.baseAddress
        print(p)
        return p!
    

    //this is  parameter and how to pass bvalue to the kernel function
    return self.kernel.apply(extent: inputExtent,
                             roiCallback: roiCallback,
                             arguments: [inputImage, reddish, greenish, blueish, normal])  // (5)

这是我试图用指针传递参数。但是代码似乎不喜欢它,它只是崩溃而没有打印错误。

这里是金属函数

extern "C"  namespace coreimage                // (3)

//this is how you define parameter on the top of the function
float4 dyeInThree(sampler src,
                  float3 redVector,
                  float3 greenVector,
                  float3 blueVector,
                  device float3 *a) 

还有其他方法可以将参数传递给我的金属代码吗?

【问题讨论】:

【参考方案1】:

我对您的用例采用了这个答案: https://***.com/a/58706038/16896928

这是我用于内存分配的:

var dummyColors = [
            SIMD3<Float>(x: 1.1, y: 0.1, z: 0.1), 
            SIMD3<Float>(x: 0.1, y: 1.1, z: 0.1),
            SIMD3<Float>(x: 0.1, y: 0.1, z: 1.1)
        ]

let pointer = UnsafeMutableRawPointer.allocate(
            byteCount: 3 * MemoryLayout<SIMD3<Float>>.stride,
            alignment: MemoryLayout<SIMD3<Float>>.alignment)
let sPointer = dummyColors.withUnsafeMutableBufferPointer  (buffer) -> UnsafeMutablePointer<SIMD3<Float>> in
            let p = pointer.initializeMemory(as: SIMD3<Float>.self,
            from: buffer.baseAddress!,
            count: buffer.count)
            return p
        
let data = Data(bytesNoCopy: sPointer, count: 3 * MemoryLayout<SIMD3<Float>>.stride, deallocator: .free)

在将缓冲区传递给内核之前,您需要将其转换为 NSData。这是 Metal 函数声明:

extern "C"  namespace coreimage                // (3)
    float4 dyeInThree(sampler src,
                      float3 redVector,
                      float3 greenVector,
                      float3 blueVector,
                      constant float3 a[]) 

注意“常量”命名空间而不是“设备”。否则 Metal 编译器会在运行时报错。

【讨论】:

【参考方案2】:

您使用withUnsafeMutableBufferPointer 获得的指针仅在您传递给函数的闭包内有效。您需要为参数分配更“永久”的存储空间。

您可以先使用UnsafeMutableBufferPointer.allocate 之类的东西来分配内存,但您必须在某处跟踪内存,因为在使用完之后您需要deallocate

【讨论】:

喜欢这个?我的代码仍然无法正常工作。它没有给出图像结果。我只检查了整数参数,它仍然有效。一定是参数? ` let normal = UnsafeMutablePointer.allocate(capacity: dummyColors.count) //loop var increment = 0 for i in dummyColors (normal + increment).initialize(to: i) increment += 1 `

以上是关于如何将数组从 Swift 传递到 MSL 参数(C++)的主要内容,如果未能解决你的问题,请参考以下文章

如何将数组从 C 传递到嵌入式 python 脚本

将结果从 Swift 数组传递到 Segue 到描述

如何使用通知将字符串数据从 swift 传递到目标 c 类

如何将2D数组作为参数从C#传递给python

如何将回调对象从 Swift 传递到 Objective C 类并用作回调?

从 Objective-C 到 Swift 的 Swift 传递块