为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 Go 中获取指向 Interface{} 底层值的指针

如何在 Go 中获取指向 Interface{} 底层值的指针

Go
泛舟湖上清波郎朗 2023-07-17 15:15:53
我使用 cgo 与 Go 中的 C 代码交互,并且需要使用指向对象中基础值的指针来调用 C 函数Interface{}。该值将是任何原子基元类型(不包括complex64/ complex128)或string。我希望我能够做这样的事情来获取ptr以下地址unsafe.Pointer:unsafe.Pointer(reflect.ValueOf(ptr).UnsafeAddr())但这会导致恐慌,因为该值无法寻址。已知该值将始终是上面指定的类型之一(最多为 64 位),并且我只需要将这个值赋予 C 函数即可。请注意,有多个 C 函数,并且将根据不同的不相关参数调用不同的函数。我还尝试使用类型 switch 语句来解决这个问题,但是我发现即使在类型断言完成之后我也无法获取值的地址。我能够将值分配给临时副本,然后获取这些副本的地址,但如果可能的话,我宁愿避免制作这些副本。
查看完整描述

1 回答

?
宝慕林4294392

TA贡献2021条经验 获得超8个赞

interface{}有自己的结构:


type eface struct {

    typ *rtype

    val unsafe.Pointer

}

rtype另一方面,您无法直接或通过链接访问,即使您将复制整个 rtype,它也可能在将来被更改(不推荐使用)。


但问题是,您可以将指针类型替换为unsafe.Pointer(它可以是具有相同大小的其他任何类型,但指针很惯用,因为每种类型都有自己的指针):


type eface struct {

    typ, val unsafe.Pointer

所以,现在我们可以获取 eface 中包含的值:


func some_func(arg interface{}) {

   passed_value := (*eface)(unsafe.Pointer(&arg)).val

   *(*byte)(passed_value) = 'b'

}


some_var := byte('a')


fmt.Println(string(some_var)) // 'a'


some_func(some_var)

fmt.Println(string(some_var)) // 'a', it didn't changed, just because it was copied


some_func(&some_var)

fmt.Println(string(some_var)) // 'b'

您还可能在我的存储库中看到更多用法: https://github.com/LaevusDexter/fast-cast


抱歉我的英语不好。


查看完整回答
反对 回复 2023-07-17
  • 1 回答
  • 0 关注
  • 63 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信