- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试将 lua 桥从 Swift 2 转换为 Swift 3。我不是原作者,所以我不太了解库的某些方面,原作者似乎对继续从事该项目不感兴趣。我已经完成了大部分转换,但还有一个地方我卡住了,无法弄清楚。我尝试在 SO 和 Internet 上搜索,但找不到任何可以帮助我解决问题的东西。
如果有人有兴趣查看完整的源代码,这里是我在 github 上的项目分支:https://github.com/weyhan/lua4swift (我的改动在Swift3分支)
请允许我为我遇到的错误设置上下文。有一个Userdata类,具体在方法userdataPointer<T>() -> UnsafeMutablePointer<T>
c 函数 lua_touserdata
以 void *
形式返回用户数据的 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/
自 Xcode 11.4 起,我收到警告消息“‘UnsafeMutableRawPointer’的初始化导致悬空指针” 对于以下代码,我将 SIMD4 从 MTLTexture 读取到数组中: let
我可能会以错误的方式解决这个问题,因为我过去没有做过很多指针运算(甚至可能没有必要)。 但是,在 Swift 中给定一个指针(UnsafeMutableRawPointer 类型),我想获得最接近(向
我正在使用 UnsafeMutableRawPointer 分配内存: let p = UnsafeMutableRawPointer.allocate(bytes: 1000, alignedTo:
如果我想获得一个变量的unsafemutablerawpointer。然而,在不创建副本或缓冲区的情况下,最好/有效的方法是什么? 下面的例子有效! var number:UInt = 5 let n
Objective-C 代码运行良好。我不知道如何将指针迁移到 Swift。 代码 Objective-C to Swift Error in * to UnsafeMutableRawPointer
我似乎无法理解在 Swift 中手动访问图像像素数据背后的方法。我正在尝试从 CGImage 创建图像蒙版,稍后可以在单独的图像上使用。我想识别特定值的所有像素并将图像中的所有其他内容转换为黑/白或
使用 Swift 3,我得到了这个,没有任何错误: private var SessionRunningContext = 0 func addObservers() { self.sessio
我有两个类都符合相同的协议(protocol): class A {} class B {} protocol P {} extension A: P {} extension B: P {} 此外,
我正在尝试获取 UnsafeMutableRawPointer 指向的地址,但我无法这样做。我也是 Swift 的新手,所以我可能会遗漏某些东西或做错了。我最好将原始值转换为 CChar。 最佳答案
我有一个 Metal 纹理,我想通过将其设为 float4 数组来从 Swift 访问它的数据(这样我就可以访问每个像素的 4 个颜色分量)。 我发现了 MTLTexture 的这个方法: getBy
如何访问由 C API(Core Audio 等)传递给 Swift 函数的 UnsafeMutableRawPointer(Swift 3 中的新功能)指向的内存之外的字节(或 Int16、 flo
以下是Swift 3.0的作品: override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [N
我在更新到 swift 3.0 时遇到了一些问题。我有以下代码: // Retrieve the Device GUID let device = UIDevice.current
我有一个 UnsafeMutableRawPointer 实例,想检索它的整数表示形式。我正在尝试使用以下代码: let pointer : UnsafeMutableRawPointer? = ad
我知道如何使用以下方法将内存从数组复制到从索引 0 开始的 UnsafeMutableRawPointer: mutableRawPointer.copyMemory(from: bytes, byt
在 Core Audio 框架中,用户数据可以通过 UnsafeMutableRawPointer? 传递到回调中。我想知道如何通过此 UnsafeMutableRawPointer? 传递结构通过引
我正在尝试转换此源代码: BluetoothDeviceAddress *deviceAddress = malloc(sizeof(BluetoothDeviceAddress)); Swift,这
我只是将我的 iOS 应用程序的代码更新为 Swift 3,这行代码让我很困惑: let dataProvider:CGDataProvider? = CGDataProviderCreateWith
我正在尝试将 Objective-C 源代码转换为 Swift。 在 Objective-C 中,下面的代码 myView = (__bridge UIView *)([SmartPlayerSDK
我正在尝试将 Objective C 代码转换为 swift。 UInt8* data = calloc(bytesPerRow, height); 当我快速转换它时,它返回“UnsafeMutabl
我是一名优秀的程序员,十分优秀!