C++ 捕获HID键盘事件
下面的代码仅适用于一个输入设备。不幸的是,我需要捕获大约12个不同的HID设备RFID阅读器,所以我想知道是否有人知道如何调整代码以处理12个不同的输入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.
#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