C++ 捕获HID键盘事件

C++ 捕获HID键盘事件,c++,c,linux,input,hid,C++,C,Linux,Input,Hid,下面的代码仅适用于一个输入设备。不幸的是,我需要捕获大约12个不同的HID设备RFID阅读器,所以我想知道是否有人知道如何调整代码以处理12个不同的输入 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <fcntl.h> #include <dirent.

下面的代码仅适用于一个输入设备。不幸的是,我需要捕获大约12个不同的HID设备RFID阅读器,所以我想知道是否有人知道如何调整代码以处理12个不同的输入

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <dirent.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/time.h>
#include <termios.h>
#include <signal.h>

int main(int argc, char* argv[])
{
    struct input_event ev[64];
    int fevdev = -1;
    int result = 0;
    int size = sizeof(struct input_event);
    int rd;
    int value;
    char name[256] = "Unknown";
    char *device = "/dev/input/event3";


    fevdev = open(device, O_RDONLY);
    if (fevdev == -1) {
        printf("Failed to open event device.\n");
        exit(1);
    }

    result = ioctl(fevdev, EVIOCGNAME(sizeof(name)), name);
    printf ("Reading From : %s (%s)\n", device, name);

    printf("Getting exclusive access: ");
    result = ioctl(fevdev, EVIOCGRAB, 1);
    printf("%s\n", (result == 0) ? "SUCCESS" : "FAILURE");

    while (1)
    {
        if ((rd = read(fevdev, ev, size * 64)) < size) {
            break;
        }

        value = ev[0].value;

        if (value != ' ' && ev[1].value == 1 && ev[1].type == 1) {
            printf ("Code[%d]\n", (ev[1].code));
        }
    }

    printf("Exiting.\n");
    result = ioctl(fevdev, EVIOCGRAB, 1);
    close(fevdev);
    return 0;
}
为每个设备调用open,然后使用select或epoll一起监视所有文件描述符,这样您就可以检测哪些设备有数据可供随时读取

更新:例如:

struct event_device
{
    char *device;
    int fd;
};

int main(int argc, char* argv[])
{
    struct input_event ev[64];
    int numevents;
    int result = 0;
    int size = sizeof(struct input_event);
    int rd;
    char name[256];
    char* device[12];
    event_device evdevs[12], *evdev;
    int numevdevs = 0;
    fd_set fds;
    int maxfd;

    device[0] = "/dev/input/event3";
    device[1] = "/dev/input/event4";
    // and so on...

    for (int i = 0; i < 12; ++i) {
        evdev = &evdevs[numevdevs];

        evdev->device = device[i];
        evdev->fd = open(evdev->device, O_RDONLY);
        if (evdev->fd == -1) {
            printf("Failed to open event device: %s.\n", evdev->device);
            continue;
        }
        ++numevdevs;

        memset(name, 0, sizeof(name));
        result = ioctl(evdev->fd, EVIOCGNAME(sizeof(name)), name);
        printf ("Reading From : %s (%s)\n", evdev->device, name);

        printf("Getting exclusive access: ");
        result = ioctl(evdev->fd, EVIOCGRAB, 1);
        printf("%s\n", (result == 0) ? "SUCCESS" : "FAILURE");
    }

    if (numevdevs == 0) {
        exit(1);
    }

    while (1)
    {
        FD_ZERO(&fds);
        maxfd = -1;

        for (int i = 0; i < numevdevs; ++i) {
            evdev = &evdevs[i];
            FD_SET(evdev->fd, &fds);
            if (maxfd < evdev->fd) maxfd = evdev->fd;
        }

        result = select(maxfd+1, &fds, NULL, NULL, NULL);
        if (result == -1) {
            break;        
        }

        for (int i = 0; i < numevdevs; ++i) {
            evdev = &evdevs[i];

            if (!FD_ISSET(evdev->fd, &fds)) {
                continue;
            }

            if ((rd = read(evdev->fd, ev, size * 64)) < size) {
                continue;
            }

            numevents = rd / size;
            for (int j = 0; j < numevents; ++j) {
                printf ("%s: Type[%d] Code[%d] Value[%d]\n", evdev->device, ev[j].type, ev[j].code, ev[j].value);
            }
        }
    }

    printf("Exiting.\n");

    for (int i = 0; i < numevdevs; ++i) {
        evdev = &evdevs[i];
        result = ioctl(evdev->fd, EVIOCGRAB, 0);
        close(evdev->);
    }

    return 0;
}

我试过了,但没用。似乎input_事件只有一个,即使我有两个或多个设备。是否有任何方法可以检查事件代码ev[1]。对发送该信息的设备进行编码?不幸的是,您必须监视每个设备并检测每个设备何时向您发送事件。事件本身无法识别发送它的设备。我已经用一个例子更新了我的答案。要取消绑定设备,应该在代码末尾将0而不是1传递给ioctl