Linux:试图通过ioctl获取操纵杆供应商和产品ID,取而代之的是EIN
发布时间:2020-12-14 00:05:50 所属栏目:Linux 来源:网络整理
导读:我试图在Ubuntu上读取USB操纵杆的名称,供应商ID和产品ID(特别是我在Ubuntu 13.10 x64上使用有线Xbox 360打击垫).我可以读取名称,但在尝试阅读供应商和产品ID时,我收到EINVAL错误.代码如下: if (plugged[index]){ char name[32]; std::snprintf(name,sizeof(
我试图在Ubuntu上读取USB操纵杆的名称,供应商ID和产品ID(特别是我在Ubuntu 13.10 x64上使用有线Xbox 360打击垫).我可以读取名称,但在尝试阅读供应商和产品ID时,我收到EINVAL错误.代码如下:
if (plugged[index]) { char name[32]; std::snprintf(name,sizeof(name),"/dev/input/js%u",index); // Open the joystick's file descriptor (read-only and non-blocking) m_file = ::open(name,O_RDONLY | O_NONBLOCK); if (m_file >= 0) { // Retrieve the axes mapping ioctl(m_file,JSIOCGAXMAP,m_mapping); // Get the name char joyname[128]; if (ioctl(m_file,JSIOCGNAME(128),joyname) < 0) { m_name = "Unknown Joystick"; } else { m_name = joyname; } // Get vendor and product IDs input_id inpid; if (ioctl(m_file,EVIOCGID,&inpid) < 0) { if (errno == EBADF) printf("EBADFn"); if (errno == EFAULT) printf("EFAULTn"); if (errno == ENOTTY) printf("ENOTTYn"); if (errno == EINVAL) printf("EINVALn"); m_manufacturerID = 0; m_productID = 0; } else { m_manufacturerID = inpid.vendor; m_productID = inpid.product; } // Reset the joystick state m_state = JoystickState(); return true; } else { return false; } } else { return false; } 读取供应商和产品ID的代码段是: ioctl(m_file,&inpid) 根据man page for ioctl,EINVAL请求(EVIOCGID)或argp(inpid)无效. 如何确定哪个无效? 解决方法
在做了一些挖掘之后,我发现ioctl(m_file,EVIOCGID和& inpid)失败的原因是我打开的设备是操纵杆(/ dev / input / js)而EVIOCGID ioctl是用于事件设备(/ dev / input / event)因此失败了.不幸的是,没有JSIOCGID ioctl所以我不得不改变策略.相反,我使用
udev来访问操纵杆的供应商和产品ID.这是我正在使用的代码:
// Use udev to look up the product and manufacturer IDs struct udev *udev = udev_new(); if (udev) { char sysname[32]; std::snprintf(sysname,sizeof(sysname),"js%u",index); struct udev_device *dev = udev_device_new_from_subsystem_sysname(udev,"input",sysname); dev = udev_device_get_parent_with_subsystem_devtype(dev,"usb","usb_device"); if (!dev) { err() << "Unable to find parent USB device" << std::endl; } std::stringstream ss; ss << std::hex << udev_device_get_sysattr_value(dev,"idVendor"); ss >> m_manufacturerID; ss.clear(); ss.str(""); ss << std::hex << udev_device_get_sysattr_value(dev,"idProduct"); ss >> m_productID; udev_device_unref(dev); udev_unref(udev); } else { err() << "Cannot create udev" << std::endl; } 使用udev,我能够在Ubuntu 13.10 x64上一致地检索USB游戏杆的供应商和产品ID. UPDATE 我进一步测试了这个: > Linux Mint 16 x64 在所有情况下,这段代码都很有效. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |