gpt4 book ai didi

ios - 如何将 C 函数返回的 'void *' 转换为 Swift 3 中的 'UnsafeMutableRawPointer'?

转载 作者:可可西里 更新时间:2023-11-01 03:55:39 37 4
gpt4 key购买 nike

我正在尝试将 lua 桥从 Swift 2 转换为 Swift 3。我不是原作者,所以我不太了解库的某些方面,原作者似乎对继续从事该项目不感兴趣。我已经完成了大部分转换,但还有一个地方我卡住了,无法弄清楚。我尝试在 SO 和 Internet 上搜索,但找不到任何可以帮助我解决问题的东西。

如果有人有兴趣查看完整的源代码,这里是我在 github 上的项目分支:https://github.com/weyhan/lua4swift (我的改动在Swift3分支)

请允许我为我遇到的错误设置上下文。有一个Userdata类,具体在方法userdataPointer<T>() -> UnsafeMutablePointer<T> c 函数 lua_touserdatavoid * 形式返回用户数据的 block 地址指针类型。

用 Swift 2 编写的原始代码:

public class Userdata: StoredValue {

public func userdataPointer<T>() -> UnsafeMutablePointer<T> {
push(vm)
let ptr = lua_touserdata(vm.vm, -1)
vm.pop()
return UnsafeMutablePointer<T>(ptr)
}

public func toCustomType<T: CustomTypeInstance>() -> T {
return userdataPointer().memory
}

public func toAny() -> Any {
return userdataPointer().memory
}

override public func kind() -> Kind { return .Userdata }

}

使用 Xcode 8 迁移工具转换后,Xcode 提示返回行错误 Cannot invoke initializer for type 'UnsafeMutablePointer<T>' with an argument list of type '(UnsafeMutableRawPointer?)' :

return UnsafeMutablePointer<T>(ptr)

我已经修复了它:

return (ptr?.assumingMemoryBound(to: T.self))!

经过上述更改后,现在 Xcode 8 现在会提示 createCustomType 中的调用语句:

public func createCustomType<T: CustomTypeInstance>(setup: (CustomType<T>) -> Void) -> CustomType<T> {
lua_createtable(vm, 0, 0)
let lib = CustomType<T>(self)
pop()

setup(lib)

registry[T.luaTypeName()] = lib
lib.becomeMetatableFor(lib)
lib["__index"] = lib
lib["__name"] = T.luaTypeName()

let gc = lib.gc
lib["__gc"] = createFunction([CustomType<T>.arg]) { args in
let ud = args.userdata

// ******* Here's the line that is causing problem in Swift 3
(ud.userdataPointer() as UnsafeMutablePointer<Void>).destroy()
// *******

let o: T = ud.toCustomType()
gc?(o)
return .Nothing
}

if let eq = lib.eq {
lib["__eq"] = createFunction([CustomType<T>.arg, CustomType<T>.arg]) { args in
let a: T = args.customType()
let b: T = args.customType()
return .Value(eq(a, b))
}
}
return lib
}

我卡住的地方是这条线:

(ud.userdataPointer() as UnsafeMutablePointer<Void>).destroy()

我相信原作者试图清除userdataPointer()返回的指针所在的内存块。调用指向。

使用 Xcode 8 自动迁移工具将上面的行转换如下:

(ud.userdataPointer() as UnsafeMutableRawPointer).deinitialize()

但是 Xcode 现在会提示 Cannot convert call result type 'UnsafeMutablePointer<_>' to expected type 'UnsafeMutableRawPointer' .

根据我的研究,userdataPointer 中返回行的变化|似乎是正确的,所以我认为问题在于转换为 UnsafeMutableRawPointer。我试过将类型转换放到 UnsafeMutableRawPointer并调用 ud.userdataPointer().deinitialize()直接但我收到此错误 Generic parameter 'T' could not be inferred .

我尝试过的其他事情是将 UnsafeMutablePointer 转换为 UnsafeMutableRawPointer 但它总是导致 Xcode 8 提示这样或那样的事情。关于如何让它发挥作用的任何建议?

最佳答案

您可能已经发现,Swift 3 尝试在指针方面提供更好的类型安全性。 UnsafeMutablePointer现在只能表示指向已知类型实例的指针。在 Swift 2 中,一个 C void *UnsafeMutablePointer<Void> 代表,允许以相同方式处理 void 和非 void 指针,包括尝试调用指向类型的反初始化程序,这就是 destroy()有问题的代码行中的方法:

  (ud.userdataPointer() as UnsafeMutablePointer<Void>).destroy()

在 Swift 3 中,pointee 上的反初始化器使用 deinitialize() 调用UnsafeMutablePointer 的方法结构体。看来移民助理糊涂了。线路

(ud.userdataPointer() as UnsafeMutableRawPointer).deinitialize()

没有什么意义,因为 (1) UnsafeMutablePointer无法使用 as 进行转换至 UnsafeMutableRawPointer ; (2) UnsafeMutableRawPointer没有deinitialize()方法。在 Swift 3 中,UnsafeMutableRawPointer是一个特殊的类型来表示 void* .迁移工具为什么会犯这个错误其实很好理解:它盲目地替换了destroy()。与 deinitialize()UnsafeMutablePointer<Void>使用相应的 Swift 3 类型 UnsafeMutableRawPointer ,却没有意识到转换不起作用。

我不太明白为什么要调用destroy()在 void 指针上可以在 Swift 2 中工作。也许这是程序中的错误,或者某些编译器技巧允许调用正确的反初始化器。在对代码了解不够的情况下,我只能建议对其进行分析以找出该指针指向的类型是什么 destroy()。被称为。例如,如果我们确定它始终是占位符类型 T在以下行中使用:

   let o: T = ud.toCustomType()

然后违规行就变成了

  (ud.userdataPointer() as UnsafeMutablePointer<T>).deinitialize()

我们需要括号中的转换以允许编译器推断泛型参数。

感谢您提出一个有趣的问题。顺便说一句,一旦你克服了这个障碍,你很可能会遇到其他问题。跳出来的一件事是 UnsafeMutablePointer没有 .memory在 swift 3 中;你必须使用 .pointee相反。

这是一个更新。在 Linux 上玩 Swift 2.2 之后,我意识到调用 destroy()UnsafeMutablePointer<A> 上转换为UnsafeMutablePointer<Void>不会调用 A 的析构器,即使它有一个。所以,你必须小心那条线......

关于ios - 如何将 C 函数返回的 'void *' 转换为 Swift 3 中的 'UnsafeMutableRawPointer'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39872452/

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