gpt4 book ai didi

c - Swift2 @convention(c) 与 char* 和 type**

转载 作者:行者123 更新时间:2023-11-30 10:08:34 27 4
gpt4 key购买 nike

我正在尝试编写指向 c 方法的指针,如下所示:

//c signature:
typedef void (*startDocumentSAXFunc) (void *ctx);

//Swift2 working code
let startDocument: @convention(c) (UnsafeMutablePointer<Void>) -> Void = { (ctx) -> Void in
NSLog("Start Document")

}
  • 我找不到 xmlChar** 使用的类型
    //c signature    typedef void (*startElementSAXFunc) (void *ctx,                const xmlChar *name,                const xmlChar **atts);    //Swift2 code    let startElement: @convention(c) (UnsafeMutablePointer, UnsafePointer, ???) -> Void  = { (ctx, name, attributes) -> Void in        NSLog("Start Element \(name), \(attributes)")    }
  • 我找不到 const char* 使用什么类型
    //c signature    typedef void (XMLCDECL *errorSAXFunc) (void *ctx,                const char *msg, ...);    //Swift2     let error: @convention(c) (UnsafeMutablePointer, ???) -> Void =    { (ctx, msg) -> Void in        NSLog("Error \(msg)")    }

我尝试了 UnsafePointer 类型,但它不起作用。

这里的目标是能够使用比 NSXML lib 更快的 libXML。

感谢您的帮助!

最佳答案

C 函数类型

void (*startElementSAXFunc) (void *ctx,
const xmlChar *name,
const xmlChar **atts);

映射到 Swift 为

(UnsafeMutablePointer<Void>, UnsafePointer<xmlChar>, UnsafeMutablePointer<UnsafePointer<xmlChar>>) -> Void

所以有效的startElementSAXFunc

func onStartElement(ctx: UnsafeMutablePointer<Void>,
name: UnsafePointer<xmlChar>,
atts: UnsafeMutablePointer<UnsafePointer<xmlChar>>) {

// ...
}

并且可以将其分配给处理程序而无需任何强制转换:

var handler = xmlSAXHandler()
handler.initialized = XML_SAX2_MAGIC
// ...
handler.startElement = onStartElement

现在 xmlCharunsigned char 的类型别名,即 UInt8在 Swift 中,与 CChar 又名 Int8 不同,因此如果转换传递的字符,则需要额外的转换到 onStartElement 中的 Swift 字符串:

    let sName = String.fromCString(UnsafePointer(name))!
print("start element, name = ", sName)

atts 是一个指向字符指针数组的指针,你可以像在 C: 中一样遍历该数组:

    if atts != nil {
var ptr = atts
while ptr[0] != nil && ptr[1] != nil {
let key = String.fromCString(UnsafePointer(ptr[0]))!
let value = String.fromCString(UnsafePointer(ptr[1]))!
print("attr:", key, "=", value)
ptr += 2
}
}

以类似的方式,您可以实现endElementSAXFunccharactersSAXFunc

<小时/>

但是,使用 errorSAXFunc 时,存在一个大问题:该函数使用可变参数列表,因此不能是用 Swift 实现的,所以你运气不好。

以下内容编译并似乎运行:

let onError : @convention(c) (UnsafeMutablePointer<Void>, UnsafePointer<xmlChar>)->Void = {
(ctx, msg) in

let sMsg = String.fromCString(UnsafePointer(msg))!
print("error:", sMsg)
}

handler.error = unsafeBitCast(onError, errorSAXFunc.self)

但据我所知,这是未定义的行为。这也没有帮助,因为你会得到错误格式字符串仅(在我的测试用例中只是 %s)。

关于c - Swift2 @convention(c) 与 char* 和 type**,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34589186/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com