在 Go 中检查字节序的任何更好的方法
Any better way to check endianness in Go
我正在编写一个小程序来使用 Go 检查字节序:
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
转换为 *byte
。
但是正如https://golang.org/pkg/unsafe/中提到的:
Package unsafe contains operations that step around the type safety of Go programs.
Packages that import unsafe may be non-portable and are not protected by the Go 1 compatibility guidelines.
是否有更好的方法来确定字节顺序,还是我必须使用不安全的包?
也许这个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
}
}
你想做的是特定于体系结构的,据我所知,Go 并没有做很多事情来帮助你确定主机的字节顺序。您使用不安全指针的解决方案可能是您能做的最好的。
如果你知道你想要说话的字节顺序和相应的 encode/decode,你可以使用 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 的建议,即使用构建约束静态定义所需的字节顺序(或主机字节顺序):
For months now our code has had:
var hbo = binary.LittleEndian // hack - we want host byte order!
so we can use encoding.Binary to read things.
将其放入名为 byteorder_amd64.go 的文件中,然后
它不再是一个黑客。它不需要在标准中
图书馆。
希望对您有所帮助...
虽然仍然依赖于 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.")
}
}
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
我正在编写一个小程序来使用 Go 检查字节序:
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
转换为 *byte
。
但是正如https://golang.org/pkg/unsafe/中提到的:
Package unsafe contains operations that step around the type safety of Go programs.
Packages that import unsafe may be non-portable and are not protected by the Go 1 compatibility guidelines.
是否有更好的方法来确定字节顺序,还是我必须使用不安全的包?
也许这个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
}
}
你想做的是特定于体系结构的,据我所知,Go 并没有做很多事情来帮助你确定主机的字节顺序。您使用不安全指针的解决方案可能是您能做的最好的。
如果你知道你想要说话的字节顺序和相应的 encode/decode,你可以使用 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 的建议,即使用构建约束静态定义所需的字节顺序(或主机字节顺序):
For months now our code has had:
var hbo = binary.LittleEndian // hack - we want host byte order!
so we can use encoding.Binary to read things.
将其放入名为 byteorder_amd64.go 的文件中,然后 它不再是一个黑客。它不需要在标准中 图书馆。
希望对您有所帮助...
虽然仍然依赖于 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.")
}
}
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