Kotlin-Multiplatform 中的 CPointer

Posted

技术标签:

【中文标题】Kotlin-Multiplatform 中的 CPointer【英文标题】:CPointer in Kotlin-Multiplatform 【发布时间】: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;?.

但是怎么做呢?

【问题讨论】:

【参考方案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

【讨论】:

可能值得将链接 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())
    

【讨论】:

请为您的答案添加解释

以上是关于Kotlin-Multiplatform 中的 CPointer的主要内容,如果未能解决你的问题,请参考以下文章

在 kotlin-multiplatform 上生成 UUID?

Kotlin-multiplatform:如何执行 iOS 单元测试

如何使用 Kotlin-Multiplatform 在 iOS 应用程序的后台线程中运行任务?

C ++中的标头中的C

c中的回调和c中的指针

C\C++ 中的 LIBLINEAR