Kotlin Native中如何为带运行时偏移的C指针写入C函数地址?
解决Kotlin Native中向结构体指针偏移位置写入函数地址的问题
问题核心
CPointerVarOf这类Native互操作类型由编译器托管,不能直接调用其构造函数,需通过Kotlin Native提供的内存操作API完成指针转换与赋值。
正确实现方式
方法一:类型转换直接赋值
将偏移后的NativePtr转换为对应指针变量类型,直接赋值函数指针:
fun main() { val genericStructPointer: CPointer<out CPointed> = malloc(100)!! println("genericStructPointer: ${genericStructPointer.rawValue}") val offsetPtr = genericStructPointer.rawValue.plus(16) println("offsetPtr: $offsetPtr") val squareFunc = staticCFunction<Int, Int> { x -> x * x } println("func adr: ${squareFunc.rawValue}") // 将偏移后的NativePtr转换为COpaquePointerVar的指针 val funcPtrVar = interpretCPointer<COpaquePointerVar>(offsetPtr)!! // 直接赋值函数指针(CFunction可自动转换为COpaquePointer) funcPtrVar.value = squareFunc // 验证赋值结果 val storedFunc = funcPtrVar.value!!.reinterpret<CFunction<Int, Int>>() println("调用存储的函数:storedFunc(5) = ${storedFunc(5)}") free(genericStructPointer) }
方法二:memcpy底层内存拷贝
通过memcpy将函数指针的内存内容写入偏移位置:
fun main() { val genericStructPointer: CPointer<out CPointed> = malloc(100)!! println("genericStructPointer: ${genericStructPointer.rawValue}") val offsetPtr = genericStructPointer.rawValue.plus(16) println("offsetPtr: $offsetPtr") val squareFunc = staticCFunction<Int, Int> { x -> x * x } println("func adr: ${squareFunc.rawValue}") val funcPtrSize = sizeOf<COpaquePointer>() println("函数指针大小: $funcPtrSize") // 转换偏移指针并执行内存拷贝 val dest = interpretCPointer<CPointed>(offsetPtr)!! memcpy(dest, squareFunc, funcPtrSize.toULong()) // 验证赋值结果 val storedFunc = interpretCPointer<CFunction<Int, Int>>(offsetPtr)!! println("调用存储的函数:storedFunc(5) = ${storedFunc(5)}") free(genericStructPointer) }
关键说明
interpretCPointer<T>是Kotlin Native提供的安全转换API,用于将NativePtr转为指定类型的CPointer,规避直接调用互操作类型构造函数的错误。CFunction类型可自动与COpaquePointer互相转换,无需手动处理原始内存地址。- 务必调用
free释放malloc分配的内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Reto Mayer
相关产品推荐
相关产品推荐

