Linux:试图通过ioctl获取 *** 纵杆供应商和产品ID,取而代之的是EINVAL

Linux:试图通过ioctl获取 *** 纵杆供应商和产品ID,取而代之的是EINVAL,第1张

概述我试图在Ubuntu上读取USB *** 纵杆的名称,供应商ID和产品ID(特别是我在Ubuntu 13.10 x64上使用有线Xbox 360打击垫).我可以读取名称,但在尝试阅读供应商和产品ID时,我收到EINVAL错误.代码如下: if (plugged[index]){ char name[32]; std::snprintf(name, sizeof(name), "/dev/ 我试图在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("EBADF\n");            if (errno == EFAulT) printf("EFAulT\n");            if (errno == ENottY) printf("ENottY\n");            if (errno == EINVAL) printf("EINVAL\n");            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 IDsstruct 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
> manjaro x64
> Fedora 20 x64

在所有情况下,这段代码都很有效.

总结

以上是内存溢出为你收集整理的Linux:试图通过ioctl获取 *** 纵杆供应商和产品ID,取而代之的是EINVAL全部内容,希望文章能够帮你解决Linux:试图通过ioctl获取 *** 纵杆供应商和产品ID,取而代之的是EINVAL所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/1022084.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存