Linux设备ioctl读取时test_bit宏无法使用的技术求助
解决test_bit宏无法正常工作的问题
兄弟,太懂这种卡壳多日的憋屈感了!你自己写的那个test_bit宏逻辑上看似没问题,但Linux系统里其实有官方适配的实现,而且必须引入正确的头文件才能用——自己手写的宏很可能因为类型不匹配、系统位数适配问题翻车!
先给你划重点:
- 如果你写的是用户态程序(比如用ioctl读取输入设备的应用),直接引入
<linux/input.h>头文件就行,里面不仅有官方的test_bit宏,还包含了输入设备相关的所有常量(比如EV_KEY、KEY_ENTER这类)。 - 要是你在写内核模块,那得引入
<linux/bitops.h>(通用)或者<asm/bitops.h>(架构相关),内核里的test_bit会根据系统位数自动处理索引,比你手动按字节计算靠谱多了。
为啥你自己的宏不行?大概率是输入设备返回的位数组类型不对!内核里的位掩码默认是unsigned long数组,不是unsigned char,你按bit/8算索引,在64位系统里直接就错位了。官方宏会用BITS_PER_LONG(比如64位系统就是64)来计算,这才是正确姿势。
给你贴个用户态读取输入设备的示例代码,照着来绝对没问题:
#include <stdio.h> #include <fcntl.h> #include <linux/input.h> #include <unistd.h> #include <errno.h> int main() { int fd = open("/dev/input/event0", O_RDONLY); if (fd < 0) { perror("Failed to open input device"); return 1; } // 定义符合要求的位数组,用unsigned long类型 unsigned long ev_bit[EV_MAX / BITS_PER_LONG + 1]; if (ioctl(fd, EVIOCGBIT(0, EV_MAX), ev_bit) < 0) { perror("ioctl EVIOCGBIT failed"); close(fd); return 1; } // 用官方test_bit宏判断是否支持按键事件 if (test_bit(EV_KEY, ev_bit)) { printf("This device supports key events!\n"); } else { printf("No key event support.\n"); } close(fd); return 0; }
要是还是有问题,把你运行的代码贴出来,我帮你揪细节!
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

