首页 > 解决方案 > C/C++ 中的 Test_bit 宏

问题描述

我正在尝试通过 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();
            }
    }
}

}

标签: c++linuxkeyboard

解决方案


这是一个小样本,展示了如何test_bit使用。(我重新命名它TEST_BIT并在下面解释原因。):

#include <iomanip>
#include <iostream>

#define TEST_BIT(bit, array) (array[bit / 8] & (1 << (bit % 8)))

int main()
{
  unsigned char data[] = {
    (unsigned char)0xde,
    (unsigned char)0xad,
    (unsigned char)0xbe,
    (unsigned char)0xef
  };
  enum { nData = sizeof data / sizeof *data };
  enum { nDataBits = 8 * nData };
  for (unsigned i = 0; i < nDataBits; ++i) {
    std::cout << "Bit " << std::setw(2) << i << ": "
      << (TEST_BIT(i, data) ? 1 : 0) << '\n';
  }
  return 0;
}

输出:

Bit  0: 0
Bit  1: 1
Bit  2: 1
Bit  3: 1
Bit  4: 1
Bit  5: 0
Bit  6: 1
Bit  7: 1
Bit  8: 1
Bit  9: 0
Bit 10: 1
Bit 11: 1
Bit 12: 0
Bit 13: 1
Bit 14: 0
Bit 15: 1
Bit 16: 0
Bit 17: 1
Bit 18: 1
Bit 19: 1
Bit 20: 1
Bit 21: 1
Bit 22: 0
Bit 23: 1
Bit 24: 1
Bit 25: 1
Bit 26: 1
Bit 27: 1
Bit 28: 0
Bit 29: 1
Bit 30: 1
Bit 31: 1

Life demo on coliru

请注意:

  1. 类似函数的宏在 C++ 中是一个糟糕的选择。内联函数要好得多,因为宏不是类型安全的,但函数是。在这种情况下,适当的替代方案可能是:

    inline bool test_bit(unsigned bit, unsigned char *array)
    {
      return array[bit / 8] & (1 << (bit % 8)) != 0;
    }
  2. 宏应仅以大写命名。在实际的 C++ 编译开始之前处理宏。因此,它们完全超出了任何定义的命名空间。这可能会产生令人惊讶的效果。因此,大写命名使它们有点排他性。(或者,最好尽可能使用内联函数。)

  3. 宏从字节数组中分离出一点。因此,隔离值可能是 1、2、4、8、16、32、64、128,具体取决于测试哪个位(的结果1 << (bit % 8)),如果分别。位已设置。只要需要真值,这不是问题,因为一切!= 0 都被视为真。如果预期为 0 或 1,则结果test_bit()TEST_BIT()应另外与 0 进行比较。


推荐阅读