微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将 C 结构的 Swift 数组转换为 UnsafeMutablePointer

如何解决将 C 结构的 Swift 数组转换为 UnsafeMutablePointer

我有两个暴露给 Swift 的非常简单的 C 结构:

typedef struct FooStruct {
    uint8_t bar_value;
} FooStruct;

typedef struct FooArray {
    struct FooStruct *foos;
    uintptr_t foo_count;
} FooArray;

我还有一个公开的 C 方法,它采用 FooArray 的实例并打印每个 Foobar_value

void print_foo_array(struct FooArray array);

Xcode 为该方法自动生成的类型提示是:

print_foo_array(array: FooArray)

为了构建 FooArray 的实例,它是

FooArray(foos: UnsafeMutablePointer<FooStruct>!,foo_count: UInt)

现在,我正在尝试在 Swift 中生成一个示例数组并将其传递给打印方法。初始设置相当简单:

let fooA = FooStruct(bar_value: 23)
let fooB = FooStruct(bar_value: 19)
let swiftFooArray = [fooA,fooB]

将其包装到 FooArray 中,然后将所说的 FooArray 传递给 print_foo_array 时会出现问题。我尝试了以下方法

方法

func swift_foo_array_to_native(array: [FooStruct]) -> FooArray {
    let foos = array.withUnsafeBufferPointer { (unsafeBufferPointer: UnsafeBufferPointer<FooStruct>) -> UnsafeMutablePointer<FooStruct> in
        let mutablePointer = UnsafeMutablePointer<FooStruct>(mutating: unsafeBufferPointer.baseAddress!)
        return mutablePointer
    }
    let nativeFooArray = FooArray(foos: foos,foo_count: UInt(array.count))
    return nativeFooArray
}

print_foo_array(swift_foo_array_to_native(swiftFooArray))

方法 2

func swift_foo_array_to_native(array: [FooStruct]) -> FooArray {
    var mutableArray = array
    let foos = UnsafeMutablePointer<FooStruct>(&array)
    let nativeFooArray = FooArray(foos: foos,foo_count: UInt(array.count))
    return nativeFooArray
}

print_foo_array(swift_foo_array_to_native(swiftFooArray))

方法 3

func swift_foo_array_to_native(array: [FooStruct]) -> FooArray {
    let foos = UnsafeMutablePointer<FooStruct>.allocate(capacity: array.count)
    foos.initialize(from: array,count: array.count)
    let nativeFooArray = FooArray(foos: foos,foo_count: UInt(array.count))
    return nativeFooArray
}

print_foo_array(swift_foo_array_to_native(swiftFooArray))

上述所有方法都返回一个在其闭包外使用的指针,因此我也尝试在闭包内调用方法,如下所示:

方法 4

swiftFooArray.withUnsafeBufferPointer { (fooBufferPointer: UnsafeBufferPointer<FooStruct>) in
    let foos = UnsafeMutablePointer<FooStruct>(mutating: fooBufferPointer.baseAddress!)
    let fooArray = FooArray(foos: foos,foo_count: 2)
    print_foo_array(fooArray)
}

还有

方法 5

var mutableSwiftFooArray = swiftFooArray
print_foo_array(FooArray(foos: &mutableSwiftFooArray,foo_count: 2))

然而这些都不起作用。我总是得到:

NativeFooExperiment(33256,0x112584dc0) malloc: *** 对象错误

0x60000379f1d0:被释放的指针未分配

NativeFooExperiment(33256,0x112584dc0) malloc: *** 设置断点

malloc_error_break 调试

另一方面,为了验证 print_foo_array 是否可以正常工作,我还添加了另一个 C 方法作为完整性检查:

struct FooArray generate_foo_array(void);

在那里,它在运行时完美无缺

let generatedFoos = generate_foo_array()
print_foo_array(generatedFoos)

如何修复 FooArray 实例从 Swift 到本机库方法的传递?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。