Maison >développement back-end >Golang >Comment implémenter des IOCTL dans Golang et éviter les erreurs « Argument invalide » ?
Implémentation d'IOCTL dans Golang
Lors du portage du code de l'espace utilisateur de C vers Golang, la gestion d'IOCTL peut être un défi. Cet article traite d'un problème spécifique rencontré lors de la tentative de conversion du code C suivant :
#define MAJOR_NUM 100 #define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) static int mbox_property(int file_desc, void *buf) { return ioctl(file_desc, IOCTL_MBOX_PROPERTY, buf); }
L'équivalent Golang :
func mBoxProperty(f *os.File, buf [256]int64) { err := Ioctl(f.Fd(), IOWR(100, 0, 8), uintptr(unsafe.Pointer(&buf[0]))) } func Ioctl(fd, op, arg uintptr) error { _, _, ep := syscall.Syscall(syscall.SYS_IOCTL, fd, op, arg) if ep != 0 { return syscall.Errno(ep) } return nil } func IOWR(t, nr, size uintptr) uintptr { return IOC(IocRead|IocWrite, t, nr, size) } func IOC(dir, t, nr, size uintptr) uintptr { return (dir << IocDirshift) | (t << IocTypeshift) | (nr << IocNrshift) | (size << IocSizeshift) }
L'exécution de ce code entraîne une erreur « argument non valide ». Le problème réside dans la façon dont IOCTL() est appelé.
Une solution Wrapper
Le package "golang.org/x/sys/unix" fournit ioctl(2 ) emballages. Pour ce cas spécifique, le wrapper unix.IoctlSetInt peut être utilisé.
Considérations sur la mémoire
Il est important de noter que IoctlSetInt et d'autres wrappers IOCTL remettent un petit tampon mémoire au noyau. Le garbage collector de Go ne reconnaît pas cela, déplaçant ou désallouant potentiellement la mémoire alors qu'elle est encore utilisée par le noyau.
Pour résoudre ce problème, envisagez d'utiliser une extension C via cgo pour créer un tampon avec malloc. Cela garantit que le tampon ne sera pas déplacé ou libéré, évitant ainsi d'éventuels problèmes de mémoire.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!