unsafe.Pointer to []byte in Go

huangapple go评论107阅读模式
英文:

unsafe.Pointer to []byte in Go

问题

我正在尝试为我的Go OpenGL项目编写一个截图函数,我正在使用这里找到的OpenGL绑定库:

https://github.com/go-gl/glow

这是我正在使用的代码来进行截图,或者说,这是我正在处理的代码:

width, height := r.window.GetSize()
pixels := make([]byte, 3*width*height)

// 将缓冲区读入内存
var buf unsafe.Pointer
gl.PixelStorei(gl.UNPACK_ALIGNMENT, 1)
gl.ReadPixels(0, 0, int32(width), int32(height), gl.RGB, gl.UNSIGNED_BYTE, buf)
pixels = []byte(&buf) // <-- LINE 99

这在编译时触发了以下错误:

video\renderer.go:99: 无法将 &buf (类型为 *unsafe.Pointer) 转换为类型 []byte。

如何将 unsafe.Pointer 转换为字节数组?

英文:

I'm trying to write a screenshot function for my OpenGL project in Go, I'm using the OpenGL bindings found here:

https://github.com/go-gl/glow

This is the code I use to make a screenshot, or well, it's what I'm working on:

	width, height := r.window.GetSize()
	pixels := make([]byte, 3*width*height)

	// Read the buffer into memory
	var buf unsafe.Pointer
	gl.PixelStorei(gl.UNPACK_ALIGNMENT, 1)
	gl.ReadPixels(0, 0, int32(width), int32(height), gl.RGB, gl.UNSIGNED_BYTE, buf)
	pixels = []byte(&amp;buf) // &lt;-- LINE 99

This triggers the following error during compile time:

video\renderer.go:99: cannot convert &amp;buf (type *unsafe.Pointer) to type []byte.

How do I convert unsafe.Pointer to a byte array?

答案1

得分: 7

由于unsafe.Pointer已经是一个指针,所以你不能使用指向unsafe.Pointer的指针,而是应该直接使用它。一个简单的例子:

bytes := []byte{104, 101, 108, 108, 111}

p := unsafe.Pointer(&bytes)
str := *(*string)(p) //将其转换为字符串指针并将该指针的值赋给str
fmt.Println(str) //输出 "hello"
英文:

Since unsafe.Pointer is already a pointer, you can't use a pointer to unsafe.Pointer, but you should use it directly. A simple example:

bytes := []byte{104, 101, 108, 108, 111}

p := unsafe.Pointer(&amp;bytes)
str := *(*string)(p) //cast it to a string pointer and assign the value of this pointer
fmt.Println(str) //prints &quot;hello&quot;

答案2

得分: 0

如何将unsafe.Pointer转换为字节数组?

这可能是一个XY问题。从我所看到的情况来看,你实际上不需要将unsafe.Pointer转换为字节数组/切片。

问题的根源在于你尝试将buf传递给gl.ReadPixels。我对go-gl包不太熟悉,但看起来你应该使用gl.Ptr(data interface{})unsafe.Pointer传递给现有的缓冲区(我猜pixels就是缓冲区):

    width, height := r.window.GetSize()
    pixels := make([]byte, 3*width*height)

    // ...

    buf := gl.Ptr(&pixels[0]) // 指向pixels中第一个元素的unsafe.Pointer
    gl.ReadPixels(0, 0, int32(width), int32(height), gl.RGB, gl.UNSIGNED_BYTE, buf)
    // 也可以尝试(我相信这需要OpenGL 4.5):
    gl.ReadPixels(0, 0, int32(width), int32(height), gl.RGB, gl.UNSIGNED_BYTE, int32(len(pixels)), buf)
    // 正常访问pixels,无需转换。

尽管如此,将unsafe.Pointer转换为字节切片/数组再转回字节数组/切片是可能的。为了避免重复,我建议查看这个现有的SO问题:如何在golang中从数组的unsafe.Pointer创建数组或切片?

简而言之,如果你使用Go 1.17,你可以简单地执行以下操作以获得[]byte切片。

pixels = unsafe.Slice((*byte)(buf), desiredSliceLen)
英文:

> How do I convert unsafe.Pointer to a byte array?

This is probably an XY problem. You don't really need to convert an unsafe.Pointer to a byte array/slice from what I can see.

The root of the issue lies at your attempt in passing buf to gl.ReadPixels. I'm not familiar with the go-gl package, but it looks like you should be using gl.Ptr(data interface{}) to pass an unsafe.Pointer to an existing buffer (which I assume is what pixels is):

    width, height := r.window.GetSize()
    pixels := make([]byte, 3*width*height)

    // ...

    buf := gl.Ptr(&amp;pixels[0]) // unsafe.Pointer pointing to 1st element in pixels
    gl.ReadPixels(0, 0, int32(width), int32(height), gl.RGB, gl.UNSIGNED_BYTE, buf)
    // Also could try (I believe this requires OpenGL 4.5):
    gl.ReadPixels(0, 0, int32(width), int32(height), gl.RGB, gl.UNSIGNED_BYTE, int32(len(pixels)), buf)
    // Access pixels as normal, no need for conversion.

That said, it is possible to go from an unsafe.Pointer to a byte slice/array back to a byte array/slice. To avoid redundancy, I suggest looking at this existing SO question: How to create an array or a slice from an array unsafe.Pointer in golang?.

Long story short, though, if you have access to Go 1.17 you can simply do the following to get a []byte slice.

pixels = unsafe.Slice((*byte)(buf), desiredSliceLen)

huangapple
  • 本文由 发表于 2014年12月4日 21:24:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/27295184.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定