如何创建 UnsafeMutablePointer<UnsafeMutablePointer<UnsafeMutablePointer<Int8>> [英] How to create a UnsafeMutablePointer<UnsafeMutablePointer<UnsafeMutablePointer<Int8>>>

查看:47
本文介绍了如何创建 UnsafeMutablePointer<UnsafeMutablePointer<UnsafeMutablePointer<Int8>>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Swift 的 C API,对于我需要调用的方法之一,我需要给出一个

UnsafeMutablePointer>>

更多信息:

Swift 接口:

public func presage_predict(prsg: presage_t, _ result: UnsafeMutablePointer>) ->presage_error_code_t

原始 C:

presage_error_code_t presage_predict(presage_t prsg, char*** 结果);

解决方案

一般来说,如果一个函数接受一个 UnsafePointer 参数然后你可以通过 & 传递一个 T 类型的变量,就像在inout"参数中一样.在您的情况下, T

UnsafeMutablePointer>

这是char **的Swift映射.所以你可以调用C函数作为

var 预测:UnsafeMutablePointer>= 零如果 presage_predict(prsg, &prediction) == PRESAGE_OK { ... }

来自 Presage 库的文档和示例代码我理解这会分配一个字符串数组并分配这个数组的地址到 prediction 指向的变量.为了避免内存泄漏,这些字符串最终必须被释放与

presage_free_string_array(预测)

为了证明这确实有效,我采用了第一个presage_c_demo.c 上的演示代码的一部分并翻译了它到斯威夫特:

//复制 C 字符串以避免过早释放:let past = strdup("你不是说了吗")让未来 = strdup("")func get_past_stream(arg: UnsafeMutablePointer) ->UnsafePointer{返回 UnsafePointer(过去)}func get_future_stream(arg: UnsafeMutablePointer) ->UnsafePointer{返回 UnsafePointer(未来)}var prsg = presage_t()presage_new(get_past_stream, nil, get_future_stream, nil, &prsg)var 预测:UnsafeMutablePointer>= 零如果 presage_predict(prsg, &prediction) == PRESAGE_OK {对于 var i = 0;预测[i] != nil;我++ {//将 C 字符串转换为 Swift `String`:让 pred = String.fromCString(prediction[i])!打印(预测[\(i)]:\(预测)")}presage_free_string_array(预测)}免费(过去)免费(未来)

这确实有效并产生了输出

<前>预测[0]:说预测[1]:说预测[2]:野蛮人预测[3]:看到预测[4]:坐预测[5]:相同

I'm working with a C API from Swift and for one of the methods that I need to call I need to give a

UnsafeMutablePointer<UnsafeMutablePointer<UnsafeMutablePointer<Int8>>>

More Info:

Swift Interface:

public func presage_predict(prsg: presage_t, _ result: UnsafeMutablePointer<UnsafeMutablePointer<UnsafeMutablePointer<Int8>>>) -> presage_error_code_t

Original C:

presage_error_code_t presage_predict(presage_t prsg, char*** result);

解决方案

Generally, if a function takes a UnsafePointer<T> parameter then you can pass a variable of type T as in "inout" parameter with &. In your case, T is

UnsafeMutablePointer<UnsafeMutablePointer<Int8>>

which is the Swift mapping of char **. So you can call the C function as

var prediction : UnsafeMutablePointer<UnsafeMutablePointer<Int8>> = nil
if presage_predict(prsg, &prediction) == PRESAGE_OK { ... }

From the documentation and sample code of the Presage library I understand that this allocates an array of strings and assigns the address of this array to the variable pointed to by prediction. To avoid a memory leak, these strings have to be released eventually with

presage_free_string_array(prediction)

To demonstrate that this actually works, I have taken the first part of the demo code at presage_c_demo.c and translated it to Swift:

// Duplicate the C strings to avoid premature deallocation:
let past = strdup("did you not sa")
let future = strdup("")

func get_past_stream(arg: UnsafeMutablePointer<Void>) -> UnsafePointer<Int8> {
    return UnsafePointer(past)
}

func get_future_stream(arg: UnsafeMutablePointer<Void>) -> UnsafePointer<Int8> {
    return UnsafePointer(future)
}

var prsg = presage_t()
presage_new(get_past_stream, nil, get_future_stream, nil, &prsg)

var prediction : UnsafeMutablePointer<UnsafeMutablePointer<Int8>> = nil
if presage_predict(prsg, &prediction) == PRESAGE_OK {

    for var i = 0; prediction[i] != nil; i++ {
        // Convert C string to Swift `String`:
        let pred = String.fromCString(prediction[i])!
        print ("prediction[\(i)]: \(pred)")
    }

    presage_free_string_array(prediction)
}

free(past)
free(future)

This actually worked and produced the output

prediction[0]: say
prediction[1]: said
prediction[2]: savages
prediction[3]: saw
prediction[4]: sat
prediction[5]: same

这篇关于如何创建 UnsafeMutablePointer&lt;UnsafeMutablePointer&lt;UnsafeMutablePointer&lt;Int8&gt;&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆