这段代码是一个名为 VirtualDevice 的类的实现,其中包含了三个函数:/n/n1. FindDeviceNode:该函数的作用是在输入设备节点中查找指定名称的节点,并将节点名称存储在 node 参数中。如果没有找到,则返回 false,否则返回 true。/n/n2. Execute:该函数会执行给定的命令,并将执行结果存储在 results 参数中。/n/n3. GetInputDeviceNodes:该函数会获取输入设备的节点信息,并将其存储在 nodes 参数中。/n/n以下是代码的关键行注释:/n/nc++/nbool VirtualDevice::FindDeviceNode(const std::string &name, std::string &node)/n{/n CALL_DEBUG_ENTER; // 进入调试模式/n std::map<std::string, std::string> nodes; // 定义一个 map 用于存储输入设备节点信息/n GetInputDeviceNodes(nodes); // 获取输入设备节点信息/n FI_HILOGD(/'There are %{public}zu device nodes./', nodes.size()); // 输出节点数量/n/n std::map<std::string, std::string>::const_iterator cItr = nodes.find(name); // 查找指定名称的节点/n if (cItr == nodes.cend()) { // 如果未找到节点/n FI_HILOGE(/'No virtual stylus is found./'); // 输出错误日志/n return false; // 返回 false/n }/n FI_HILOGD(/'Node name : '%/{public}s'./', cItr->second.c_str()); // 输出找到的节点名称/n std::ostringstream ss; // 定义一个字符串流/n ss << /'/dev/input//' << cItr->second; // 拼接节点路径/n node = ss.str(); // 将节点路径存储在 node 变量中/n return true; // 返回 true/n}/n/nvoid VirtualDevice::Execute(const std::string &command, std::vector<std::string> &results)/n{/n CALL_DEBUG_ENTER; // 进入调试模式/n FI_HILOGD(/'Execute command:%{public}s./', command.c_str()); // 输出执行的命令/n char buffer[DEFAULT_BUF_SIZE] {}; // 定义一个字符数组用于存储命令执行结果/n FILE *pin = popen(command.c_str(), /'r/'); // 执行命令/n if (!pin) { // 如果执行失败/n FI_HILOGE(/'Failed to popen command./'); // 输出错误日志/n return; // 返回/n }/n while (!feof(pin)) { // 循环读取命令执行结果/n if (fgets(buffer, sizeof(buffer), pin) != nullptr) { // 读取结果/n results.push_back(buffer); // 将结果存储在 results 中/n }/n }/n FI_HILOGD(/'Close phandle./'); // 输出关闭 phandle 日志/n pclose(pin); // 关闭执行的进程/n}/n/nvoid VirtualDevice::GetInputDeviceNodes(std::map<std::string, std::string> &nodes)/n{/n CALL_DEBUG_ENTER; // 进入调试模式/n std::string command = /'cat /proc/bus/input/devices/'; // 定义获取输入设备节点信息的命令/n std::vector<std::string> results; // 定义一个 vector 用于存储命令执行结果/n Execute(command, results); // 执行命令/n if (results.empty()) { // 如果获取节点信息失败/n FI_HILOGE(/'Failed to list devices./'); // 输出错误日志/n return; // 返回/n }/n const std::string kname { /'Name=/' }; // 定义字符串 /'Name=/''/n const std::string kevent { /'event/' }; // 定义字符串 /'event/'/n std::string name; // 定义一个字符串用于存储设备名称/n for (const auto &item : results) { // 遍历命令执行结果/n FI_HILOGD(/'item:%{public}s./', item.c_str()); // 输出当前结果/n if (item[0] == 'N') { // 如果结果以 'N' 开头/n std::string::size_type spos = item.find(kname); // 查找 /'Name=/'' 的位置/n if (spos != std::string::npos) { // 如果找到 /'Name=/''/n spos += kname.size(); // 更新 spos/n std::string::size_type tpos = item.find(/'/', spos); // 查找 /'Name=/'' 后面的双引号的位置/n if (tpos != std::string::npos) { // 如果找到双引号/n name = item.substr(spos, tpos - spos); // 获取设备名称/n }/n }/n } else if (!name.empty() && (item[0] == 'H')) { // 如果结果以 'H' 开头,并且设备名称不为空/n std::string::size_type spos = item.find(kevent); // 查找 /'event/' 的位置/n if (spos != std::string::npos) { // 如果找到 /'event/'/n std::map<std::string, std::string>::const_iterator cItr = nodes.find(name); // 查找设备名称对应的节点/n if (cItr != nodes.end()) { // 如果节点存在/n nodes.erase(cItr); // 删除节点/n }/n std::string::size_type tpos = spos + kevent.size(); // 更新 tpos/n while (std::isalnum(item[tpos])) { // 循环查找 event 节点编号/n ++tpos; // 更新 tpos/n }/n nodes.emplace(name, item.substr(spos, tpos - spos)); // 将设备名称和节点信息存储在 nodes 中/n name.clear(); // 清空设备名称/n }/n }/n }/n}/n/n/n代码中的 CALL_DEBUG_ENTERFI_HILOGDFI_HILOGE 可能是自定义的宏,用于进行调试信息输出。/n/n这段代码清晰地展示了如何使用 C++ 代码来获取和解析输入设备节点信息,并执行系统命令。代码中使用了 std::mapstd::vectorstd::stringstd::ostringstream 等容器和数据类型,以及 popenfgetspclose 等系统调用函数,体现了 C++ 在系统编程方面的强大能力。/n

C++ VirtualDevice 类代码详解:查找输入设备节点、执行命令

原文地址: https://www.cveoy.top/t/topic/nWTp 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录