Zhang Zihan
01/16/2025, 8:06 AMstaticCFunction
access non-global variables/functions?
For example, in this function, I had to use Mutex
, which is ugly and poorly readable 😢
private val tempList = mutableListOf<String>()
private val mutex = Mutex()
suspend fun getWindowTexts(): List<String> {
return mutex.withLock {
EnumWindows(
lpEnumFunc = staticCFunction { hWnd, lParam ->
val text = memScoped {
val textVar = allocArray<UShortVar>(256)
GetWindowText!!(hWnd, textVar, 256)
textVar.toKString()
}
tempList.add(text)
1
}, 0L
)
val list = tempList.toList()
tempList.clear()
list
}
}
ephemient
01/16/2025, 8:08 AMThomas
01/16/2025, 2:11 PMthis
). Pass it to lParam
parameter and you can access it from the callback. Make sure to dispose the StableRef when no longer needed, but not any earlier.Thomas
01/16/2025, 2:26 PMval list = mutableListOf<String>()
val stableRef = StableRef.create(list)
EnumWindows(
lpEnumFunc = staticCFunction { hWnd, pParam ->
val stableRef2 = pParam.toCPointer<CPointed>()!!.asStableRef<MutableList<String>>()
val list2 = stableRef2.get()
// TODO use list2
1
},
lParam = stableRef.asCPointer().toLong()
)
stableRef.dispose()
// TODO use list
ephemient
01/17/2025, 1:58 AMlParam
can be anything you want, and a StableRef
is a great way to get pointers to Kotlin objects across the C interfaceephemient
01/17/2025, 2:14 AMval cb: (String) -> Boolean = { list.add(it) }
val stableRef = StableRef.create(cb)
EnumWindows(
lpEnumFunc = staticCFunction { hWnd, param ->
val cb: (String) -> Unit = pParam.toCPointer<CPointed>()!!.asStableRef()
val text = memScoped { ... }
if (cb(text)) 1 else 0.also { SetLastError(ERROR_something) }
},
lParam = stableRef.asCPointer().toLong(),
)