【发布时间】:2018-10-17 08:45:36
【问题描述】:
我正在尝试通过 ioctl() 读取 linux 设备的输入,我在许多带有“test_bit”宏的代码示例中看到,但我发现的唯一代码是:#define test_bit(bit, array) (array[bit / 8] & (1 << (bit % 8))),但它没有工作。我得出的结论是,为了拥有这个宏,我的课程中可能需要包含一些东西。
有没有人可以帮助我解决这个问题已经好几天了?
谢谢
编辑: 这是我正在运行的代码:
void test(){
uint8_t key_b[KEY_MAX/8 + 1];
/* the events (up to 64 at once) */
const char *keyboard = "/dev/input/keyboard0";
int keybrdToCapture;
int yalv;
keybrdToCapture = open(keyboard, O_RDONLY);
memset(key_b, 0, sizeof(key_b));
ioctl(keybrdToCapture, EVIOCGKEY(sizeof(key_b)), key_b);
for (yalv = 0; yalv < KEY_MAX; yalv++) {
if (test_bit(yalv, key_b)) {
switch ( yalv)
{
case 0x1c :
dial->setMessage("Enter");
dial->show();
break;
case 0x66 :
dial->setMessage("Home");
dial->show();
break;
case 0x3b :
dial->setMessage("F1");
dial->show();
break;
case 0x3c :
dial->setMessage("F2");
dial->show();
break;
default:
dial->setMessage("Unknow for now");
dial->show();
}
}
}
}
【问题讨论】:
-
#define test_bit(bit, array) (array[bit / 8] & (1 << (bit % 8)))怎么不起作用?它似乎不是标准 C/C++ 库提供的任何东西。因此,您可以在自己的源代码中定义它。 (虽然,#defines 标识符全小写 - 不好。)通常,宏可能会被重新定义。在这种情况下,友好的编译器至少会提供一个警告。如有疑问,可将其附在#ifndef test_bit和#endif // test_bit中。 -
感谢您的回答,我对 c++ 和 linux 还很陌生,据我了解,这段代码应该检查特定字节中的特定位是否设置为 1。 (也许我完全错了,从现在起我没有得到太多帮助来解释这个问题)。但是当我在调试中按下一个键时,我可以看到我的字节中的一位从 0 变为 1,但我从未输入我的 test_bit健康)状况。也许这只是一个误解的问题。
-
array[bit / 8]将位数除以 8 以寻址array的正确字节。bit % 8计算除以 8 的余数(实际上,分隔存储 0 ... 7 的最后 3 位)。1 << (bit & 8)将 1 移到计算位的位置。最后,(array[bit / 8] & (1 << (bit % 8)))屏蔽掉除寻址之外的所有位。如果设置了,则表达式变为非 0(被解释为非假,即真)。否则,表达式变为 0(被解释为假)。当然,这个宏专用于适当的if ()或类似的东西。 -
array应该是数组类型为unsigned char的变量(或表达式)。 (char或signed char可能也可以,但签名可能会导致问题。) -
从你之前的评论中我改变了这个希望它更好:
#ifndef test_bit #define test_bit(bit, array) (array[bit / 8] & (1 << (bit % 8))) #endif。从你告诉我它应该工作......在调试我的阵列看起来像: \000\000\000\010\000\ 是正常的吗?