如何根据体系结构将其转换为不同的类型?
我正在尝试修复在armv7架构的FreeBSD上的模块 github.com/slackhq/nebula 的文件 overlay/tun_freebsd.go 的编译问题。该文件使用 syscall.Iovec 结构,该结构在
type Iovec struct {
Base *byte
Len uint64
}
这样的64位平台(如 GOOS=freebsd GOARCH=amd64)上被定义为,而在
type Iovec struct {
Base *byte
Len uint32
}
这样的32位平台(如 GOOS=freebsd GOARCH=arm)上则是。因此,我们可以要么做到
iovecs := []syscall.Iovec{
{&head[0], 4},
{&to[0], uint64(len(to))},
}
在64位平台上构建成功,或者
iovecs := []syscall.Iovec{
{&head[0], 4},
{&to[0], uint32(len(to))},
}
在32位平台上构建成功,但似乎没有办法让代码在两者上都工作。
是否有一个在两者上都能工作的解决方案,还是我必须为32位和64位分别写相同的代码,并且修改构建标签?
解决方案
在不考虑你具体用例的前提下,如果某个类型可能会因为条件编译而不同,处理该类型的最佳做法是自己使用条件编译来处理。这样你就能在每个平台上获得正确类型的值。
也就是说,int 和 uint 在32位和64位体系结构上分别是32位和64位宽度。
你所链接的文件并没有直接使用 Iovec,而是将一个 [2]Iovec 数组开头的指针作为参数传递给 syscall.Syscall。
因此我怀疑你也许可以声明你自己的 Iovec 类型,在其中使用 uint 而不是固定宽度的无符号类型。
type Iovec struct {
Base *byte
Len uint
}
并把指向该类型的指针传入系统调用:
iovecs := [2]Iovec{
{&head[0], 4},
{&to[0], uint(len(to))},
}
...
syscall.Syscall(syscall.SYS_READV, uintptr(t.fd), uintptr(unsafe.Pointer(&iovecs[0])), 2)
这在合适的体系结构上可能就能工作。但请务必进行测试以验证这一假设。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。