我正在尝试使用Go与Windows dll连接。我想要使用的DLL函数接受一个指向字节数组的指针。因此,我需要给它那个字节数组。
我正在使用syscall图书馆来调用dll,正如所示here。我的基本要求是:
我无法弄清楚如何在go中创建一个字节数组,并获得指向它的指针。这显然是一个不安全的操作,unsafe库可能会有所帮助,但我需要首先创建一个动态长度的字节数组。使用“make”创建切片对我没有帮助,除非我可以获得指向切片的支持数组的指针。
有没有其他人遇到过此或有任何想法?
答案 0 :(得分:3)
我找到了一个重要的解决方案。显然structure of a slice包含指向后备字节数组的指针,后备字节数组的长度,以及后备字节数组的容量。
我只对指向字节数组的指针感兴趣,所以我只需要切片内部数据的第一个成员。
Go unsafe.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的内部结构。
答案 1 :(得分:3)
我认为syscall.ComputerName实现https://golang.org/src/syscall/syscall_windows.go#395就是一个很好的例子。它使用uint16s,而不是字节,否则......
在您的情况下,它将是ptr := &myslice[0]
。
亚历