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

Golang:不安全的动态字节数组

Golang:不安全的动态字节数组

Go
HUWWW 2021-07-02 14:07:20
我正在尝试使用 Go 与 Windows dll 交互。我想使用的 dll 函数接受一个指向字节数组的指针。因此我需要给它那个字节数组。我使用的系统调用libary调用DLL,这表现在这里。我的基本要求是:我得到了字节数组所需的大小我创建了字节数组我必须得到一个指向字节数组的指针然后我将指针传递给 Windows dll我不知道如何在 go 中创建一个字节数组,并获得一个指向它的指针。这显然是一个不安全的操作,不安全库可能会有所帮助,但我首先需要创建一个动态长度的字节数组。使用“make”创建切片对我没有帮助,除非我可以获得指向切片的后备数组的指针。有没有其他人遇到过这个或有任何想法?
查看完整描述

2 回答

?
吃鸡游戏

TA贡献1829条经验 获得超7个赞

好吧,我找到了一个粗略的解决方案。显然,切片的结构包含一个指向支持字节数组的指针、支持字节数组的长度以及支持字节数组的容量。


我只对指向字节数组的指针感兴趣,所以我只需要切片内部数据的第一个成员。


Gounsafe.Pointer不会将切片转换为不安全指针,但会将指向切片的指针转换为不安全指针。由于我可以将不安全指针强制转换为我想要的任何旧类型的指针,因此我可以将其强制转换为指向指针的指针,从而恢复切片内部数据的第一个成员。


这是一个工作示例。我想要一个,uintptr但你可以将它转换为任何指针类型。


package main


import (

    "fmt"

    "unsafe"

)


func main() {

    // Arbitrary size

    n := 4


    // Create a slice of the correct size

    m := make([]int, n)


    // Use convoluted indirection to cast the first few bytes of the slice

    // to an unsafe uintptr

    mPtr := *(*uintptr)(unsafe.Pointer(&m))


    // Check it worked

    m[0] = 987

    // (we have to recast the uintptr to a *int to examine it)

    fmt.Println(m[0], *(*int)(unsafe.Pointer(mPtr)))

}

如果你想要一个*int,你可以做mPtr := *(**int)(unsafe.Pointer(&m))


只要切片维护此内部数据结构,这就会起作用。我绝对愿意接受不依赖于 Go 内部结构的更强大的解决方案。


查看完整回答
反对 回复 2021-07-05
  • 2 回答
  • 0 关注
  • 245 浏览
慕课专栏
更多

添加回答

举报

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