在Qt项目中获取ttyUSB设备的udev符号链接名称
获取udev自定义符号链接名称的解决方案
我之前在处理USB串口设备的udev符号链接时也碰到过一模一样的问题,udev_device_get_devnode确实只会返回原始的设备节点路径(比如ttyUSB0),不过有几个可靠的方法能拿到你自定义的符号链接名称,分享给你:
方法1:用libudev自带的符号链接遍历函数
其实libudev并没有隐藏这个功能,只是你可能没注意到udev_device_get_devlinks_list_entry这个函数——它能返回设备所有关联的符号链接列表。你可以遍历这个列表,提取出你需要的那个链接名。
下面是适配Qt项目的C++代码示例:
#include <libudev.h> #include <QString> #include <QDebug> // 假设你已经获取到了udev_device指针dev struct udev_device *dev = ...; // 获取设备的所有符号链接条目 struct udev_list_entry *links = udev_device_get_devlinks_list_entry(dev); struct udev_list_entry *current_entry; // 遍历所有符号链接 udev_list_entry_foreach(current_entry, links) { const char *full_link_path = udev_list_entry_get_name(current_entry); // 从完整路径中提取最后一段(也就是符号链接的名称) QString link_name = QString(full_link_path).split('/').last(); // 这里可以根据你的udev规则里的命名过滤,比如只保留包含"ttl-232r"的链接 if (link_name.contains("ttl-232r", Qt::CaseInsensitive)) { qDebug() << "匹配到的自定义符号链接:" << link_name; // 找到目标后可以跳出循环 break; } }
这个方法的优势是直接利用libudev的接口,不需要额外遍历文件系统,效率更高。
方法2:遍历/dev目录匹配符号链接目标
如果因为某些原因libudev的方法不适用,你也可以直接扫描/dev目录下的符号链接,通过对比链接的目标路径来找到对应你的设备的那个链接。
示例代码(Qt风格):
#include <QDir> #include <QFileInfo> #include <QDebug> #include <libudev.h> struct udev_device *dev = ...; // 获取设备的原始节点路径和sysfs路径 QString original_devnode = QString(udev_device_get_devnode(dev)); QString sys_path = QString(udev_device_get_syspath(dev)); // 遍历/dev目录下的所有符号链接 QDir dev_dir("/dev"); QFileInfoList symlinks = dev_dir.entryInfoList(QDir::SymLinks | QDir::System); foreach (const QFileInfo &link_info, symlinks) { QString target_path = link_info.symLinkTarget(); // 检查符号链接的目标是否是设备的原始节点或sysfs路径 if (target_path == original_devnode || target_path == sys_path) { qDebug() << "找到的自定义符号链接:" << link_info.fileName(); break; } }
额外注意事项
- 确保你的udev规则正确设置了
SYMLINK+="your-custom-name",比如针对TTL-232R的规则可能类似:SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="YOUR_SERIAL", SYMLINK+="ttl-232r" - 运行Qt程序时要确保有足够的权限访问
/dev目录下的设备文件和符号链接,必要时可以将用户加入dialout组。
内容的提问来源于stack exchange,提问作者Robin
相关产品推荐
相关产品推荐

