如何使用 IOServiceOpenAsFileDescriptor?

How to use IOServiceOpenAsFileDescriptor?

我连接了 USB 设备。我决定尝试编写一些代码,将 USB 设备作为 FileDescriptor 打开,例如 Linux,我可以在 fd 上使用 ioctl 函数发送命令。

我得到以下结果:

CFMutableDictionaryRef matches = IOServiceMatching(kIOUSBDeviceClassName);
    if (!matches)
    {
        std::cerr<<human_error_string(kIOReturnError)<<"\n";
        return;
    }

    io_iterator_t deviceIterator;
    kern_return_t kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matches, &deviceIterator);
    if (kr != kIOReturnSuccess)
    {
        std::cerr<<human_error_string(kr)<<"\n";
        return;
    }

    io_service_t service = IO_OBJECT_NULL;
    while((service = IOIteratorNext(deviceIterator)))
    {   
        int32_t fd = IOServiceOpenAsFileDescriptor(service, O_RDWR) //doesn't work! Returns: -1

        IOObjectRelease(service);
    }
    IOObjectRelease(deviceIterator);

然而,FD 总是 -1.. 知道为什么吗?

据我所知,macOS 上的 USB 没有任何基于 API 的文件描述符。您需要通过基于 IOUSB 的 APIs。有一些示例代码 here.

如果您想在 Linux 和 macOS 之间共享尽可能多的代码,您可以使用 libusb,它包装了 Apple 的 IOKit API 和 Linux基于 ioctl 的 USB API.

我不得不承认我不太确定 IOServiceOpenAsFileDescriptor 的用途。 source code in IOKitLib 并不是很有启发性,因为它只是连接到 XPC 服务,并且 XPC 回复中需要文件描述符。我假设该服务是在非开源或未记录的系统守护程序中实现的。

也许IOServiceOpenAsFileDescriptor用于访问块设备或串口,它们在/dev/中既有IOKit对象又有设备节点文件。一般USB设备在文件系统中是没有节点的。