我正在编写一个小程序,使用Go来检查字节序:
colnames(values)
我var i int = 0x0100
ptr := unsafe.Pointer(&i)
if 0x01 == *(*byte)(ptr) {
fmt.Println("Big Endian")
} else if 0x00 == *(*byte)(ptr) {
fmt.Println("Little Endian")
} else {
// ...
}
包将import "unsafe"
转换为*int
。
但正如https://golang.org/pkg/unsafe/中所述:
不安全打包包含的操作会绕过Go程序的类型安全。
导入不安全的软件包可能是不可携带的,并且不受Go 1兼容性准则的保护。
有没有更好的方法来确定字节序,还是我必须使用不安全的软件包?
答案 0 :(得分:4)
您想要做的是特定于体系结构的,据我所知,Go并不能帮助您确定主机的字节顺序。您使用不安全指针的解决方案可能是您可以做的最好的事情。
如果您知道要说的字节顺序并相应地进行编码/解码,则可以使用encoding/binary
软件包:https://godoc.org/encoding/binary#ByteOrder
如果您确实需要依赖于主机字节顺序,则可能是想尽一切办法避免使用设计反模式:https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
这也是围绕golang-nuts进行的有关此主题的激烈讨论,辩论的双方都表达了意见:https://groups.google.com/forum/#!topic/golang-nuts/3GEzwKfRRQw
Russ Cox建议该电子邮件线程建议使用构建约束条件来静态定义所需的字节顺序(或主机字节顺序):
几个月来,我们的代码具有:
var hbo = binary.LittleEndian // hack-我们想要主机字节顺序!
所以我们可以使用encoding.Binary读取内容。
将其放在名为byteorder_amd64.go的文件中,然后 它不再是黑客。它不必在标准中 库。
希望有帮助...
答案 1 :(得分:2)
尽管仍然依靠unsafe
软件包,但Google的TensorFlow API for Go有一个不错的解决方案(请参见tensor.go)来测试计算机的字节序:
var nativeEndian binary.ByteOrder
func init() {
buf := [2]byte{}
*(*uint16)(unsafe.Pointer(&buf[0])) = uint16(0xABCD)
switch buf {
case [2]byte{0xCD, 0xAB}:
nativeEndian = binary.LittleEndian
case [2]byte{0xAB, 0xCD}:
nativeEndian = binary.BigEndian
default:
panic("Could not determine native endianness.")
}
}
答案 2 :(得分:1)
也许这个code可以帮助您。
这可以检查机器字节顺序:
//true = big endian, false = little endian
func getEndian() (ret bool) {
var i int = 0x1
bs := (*[INT_SIZE]byte)(unsafe.Pointer(&i))
if bs[0] == 0 {
return true
} else {
return false
}
}
答案 3 :(得分:0)
var bigEndian = (*(*[2]uint8)(unsafe.Pointer(&[]uint16{1}[0])))[0] == 0
顺便说一句,我怀疑您的原始逻辑是非法的:
var i int = 0x0100
ptr := unsafe.Pointer(&i)
if 0x01 == *(*byte)(ptr) {
如果将*T
强制转换为unsafe.Pointer
,然后转换为另一类型,*U
,则U
和T
必须具有等效的内存布局。 https://golang.org/pkg/unsafe/#Pointer