英文:
unsafe.Pointer to []byte in Go
问题
我正在尝试为我的Go OpenGL项目编写一个截图函数,我正在使用这里找到的OpenGL绑定库:
这是我正在使用的代码来进行截图,或者说,这是我正在处理的代码:
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:
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(&buf) // <-- LINE 99
This triggers the following error during compile time:
video\renderer.go:99: cannot convert &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(&bytes)
str := *(*string)(p) //cast it to a string pointer and assign the value of this pointer
fmt.Println(str) //prints "hello"
答案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(&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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论