将 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 (将#修改为@)