【问题标题】:CPointer in Kotlin-MultiplatformKotlin-Multiplatform 中的 CPointer
【发布时间】:2020-04-28 15:39:35
【问题描述】:

我找不到任何关于如何在 Kotlin Multiplatform 中获取 CPointer 的示例,并且现有的文档没有多大帮助。 在我的 iOS 源代码集中,我需要构建与以下 Swift 代码等效的 Kotlin 代码(仅包括代码的相关部分):

  ...(hex: String) {

if hex.hasPrefix("#") {
    let start = hex.index(hex.startIndex, offsetBy: 1)
         let scanner = Scanner(string: hexColor)
         var hexNumber: UInt64 = 0



          if scanner.scanHexInt64(&hexNumber) {

            r = CGFloat((hexNumber & 0xff000000) >> 24) / 255
           ....

我遇到问题的具体部分是

scanner.scanHexInt64(&hexNumber)

这是 Kotlin 代码和问题

//input to function - hex: String
    val scanner = NSScanner(hex)
    if (hex.startsWith("#")) {
        scanner.scanLocation = 1u
    }
    var hexNumber : UInt32 = 0u
    /*Type mismatch.
    Required:
    CPointer<UIntVar /* = UIntVarOf<UInt> */>?
    Found:
    UInt32 /* = UInt */
     */
    //HOW TO GET CPOINTER TO hexNumber?
    scanner.scanHexInt(hexNumber)

根据文档:(link)

指针和数组映射到CPointer&lt;T&gt;?.

但是怎么做呢?

【问题讨论】:

    标签: c swift kotlin kotlin-multiplatform kotlin-native


    【解决方案1】:

    找到了我的问题的答案。必须使用

    memScoped

    memScoped {
            var pointed : UIntVar = alloc<UIntVar>()
            scanner.scanHexInt(pointed.ptr)
            val alpha: CGFloat = 1.0
            val pointedValue = pointed.value
            val r: CGFloat = (((pointedValue and 0xFF0000) shr 16)/255.0)
            ....
    }
    

    互联网上唯一的来源(关于应用它来获取指针)在这里 - link

    memScoped

    inline fun <R> memScoped(block: MemScope.() -> R): R
    Runs given block providing allocation of memory which will be automatically disposed at the end of this scope
    

    在其中使用扩展函数alloc()获取CVariable

    fun <reified T : CVariable> NativePlacement.alloc(): T
    

    然后您可以通过另一个扩展函数访问指针

    val <T : CPointed> T.ptr: CPointer<T>
    

    回想起来都非常清楚,并且很清楚最初以错误的方式解决了问题,希望通过CPointer&lt;UInt&gt; = ... 之类的方式获取指针 官方文档https://kotlinlang.org/docs/reference/native/c_interop.html

    【讨论】:

    【解决方案2】:
    import kotlinx.cinterop.UIntVar
    import kotlinx.cinterop.memScoped
    import kotlinx.cinterop.ptr
    import platform.CoreGraphics.CGFloat
    import platform.Foundation.NSScanner
    import platform.Foundation.scanHexInt
    import platform.UIKit.UIColor
    import kotlinx.cinterop.alloc
    import kotlinx.cinterop.value
    
    fun hexToUIColor(hexStr: String): UIColor {
        var cString: String = hexStr.toUpperCase()
    
        if (cString.startsWith("#")) {
            cString = cString.removePrefix("#")
        }
    
        if (cString.length != 8) {
            return UIColor.grayColor
        }
    
        var a: UInt
        var r: UInt
        var g: UInt
        var b: UInt
    
        memScoped {
            val scanner = NSScanner(cString)
            var pointed : UIntVar = alloc<UIntVar>()
            scanner.scanHexInt(pointed.ptr)
            val alpha: CGFloat = 1.0
            val pointedValue: UInt = pointed.value
    
            a = ((pointedValue and 4278190080u) shl 24) / 255u
            r = ((pointedValue and 16711680u) shl 16) / 255u
            g = ((pointedValue and 65280u) shl 8) / 255u
            b = ((pointedValue and 255u) shl 0) / 255u
    
            return UIColor(red = r.toDouble(), green = g.toDouble(), blue = b.toDouble(), alpha = a.toDouble())
        }
    }
    

    【讨论】:

    • 请为您的答案添加解释
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-08
    • 1970-01-01
    • 2019-08-20
    • 2021-07-07
    • 2023-01-30
    • 1970-01-01
    相关资源
    最近更新 更多