这是有关在Kotlin Native中定义的,由C函数调用的回调函数的一般问题。
为了便于讨论,让我们说我想要走目录文件系统递归,使用https://linux.die.net/man/3/nftw在科特林本土。(我知道还有其他方法可以使用其他C函数来执行此操作,但这不是此问题的核心。)
nftw()将一个函数用作回调:
val directory = "//some/directory"
val callback = kotlinx.cinterop.staticCFunction {
file: CPointer<ByteVar>?,
stat: CPointer<stat>?,
typeFlag: Int,
b: CPointer<FTW>? ->
val fileName = file?.toKString()
println(fileName)
val result = 0
result
}
val depth = 10
val flags = 0
platform.posix.nftw(directory, callback, depth, flags)
这适用于通过“ println()”列出文件,但是只要lambda包含任何捕获的值,我就会收到以下编译器错误:
“ kotlinx.cinterop.staticCFunction必须采用未绑定的非捕获函数或lambda”。
我的问题是:是否有关于如何从此类回调访问任何非全局状态的建议方法?
我确实想出了一个使用全局变量的讨厌的解决方法,所以这不是我要寻找的主要内容。如果有使用@ThreadLocal或其他方式的普遍接受的解决方案,请讨论。
一般适用于本机回调(不特定于nftw
)。C函数应该接受一个void* userData
参数,并在调用它时将其传递给回调。这使您可以将本地数据而不是全局数据传递给回调。即使在C / C ++中也是如此。
对于这种特殊情况(无论使用哪种语言),如果没有一些全局数据(或JIT,但不要考虑),实际上是没有办法做到的。因此,任何解决方法都必须令人讨厌。
使用@ThreadLocal
是“合理的讨厌”解决方案。
nftw
只是设计不好的C接口。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句