gpt4 book ai didi

swift - 在 Swift 中获取 ioctl 数字

转载 作者:行者123 更新时间:2023-12-04 14:46:24 25 4
gpt4 key购买 nike

我在这里想要实现的是获取用于弹出磁盘的 ioctl 编号,我已经在我的桥接头中做了:

#define DKIOCEJECT  _IO('d', 21)

NSUInteger IOEJECT = DKIOCEJECT;

...这确实对创建 ioctl 请求有效,我想做的只是在 Swift 中,而不是必须使用桥接 header

在 C 中,我通常会输入类似这样的内容来获取 ioctl 数字:

#define DKIOCEJECT _IO('d', 21)

上面通常会返回一个 ioctl 数字,我怎样才能做类似的事情,但在 Swift 中呢?


这里是所有的预处理器宏:

#define _IO(g, n)        _IOC(IOC_VOID, (g), (n), 0)

#define _IOC(inout, group, num, len) \ (inout | ((len & IOCPARM_MASK) << 16) | ((group) << 8) | (num))

#define IOCPARM_MASK 0x1fff /* parameter length, at most 13 bits */

define IOC_VOID (__uint32_t)0x20000000

最佳答案

鉴于 _IO 宏解析为单个整数常量,我们可以按照预处理器的逻辑重新实现它:

#define DKIOCEJECT                     _IO('d', 21)
#define _IO(g, n) _IOC(IOC_VOID, (g), (n), 0)
#define _IOC(inout, group, num, len) (inout | ((len & IOCPARM_MASK) << 16) | ((group) << 8) | (num))
#define IOC_VOID (unsigned long)0x20000000
#define IOCPARM_MASK 0x1fff

因此....

DKIOCEJECT  == _IO(g: 'd', n: 21)
== _IOC(IOC_VOID, ('d'), (21), 0)
== (IOC_VOID | ((0 & IOCPARM_MASK) << 16) | (('d') << 8) | (21))
== ( 0x20000000 | (0 << 16) | (('d') << 8) | (21) )
== ( 0x20000000 | 0 | (0x64 << 8) | 21 )
== ( 0x20000000 | 0x6400 | 0x15 )
== 0x20006415

// For reference:
'd' == 0x64 // asciitable.com
21 == 0x15

在 Swift 中作为文字常量:

enum MyIoctrlNumbers {
static let DKIOCEJECT: UInt = 0x20006415
}

Swift 不支持 C++ 风格的 constexpr 表达式,但如果你对运行时生成的 static 值没问题,那么试试这个:

import Foundation

func getIoctrlNumber( group: Character, n: UInt ) -> UInt {

let IOC_VOID: UInt = 0x20000000;
let g : UInt = UInt( UInt( group.asciiValue! ) << 8 );

return IOC_VOID | g | n;
}

let asInt = getIoctrlNumber( group: "d", n: 21 );
let asDec = String( asInt, radix: 10 );
let asHex = String( asInt, radix: 16 );
print( "DKIOCEJECT == " + asDec );
print( "DKIOCEJECT == 0x" + asHex );

给我这个输出:

Swift version 5.5.1 (swift-5.5.1-RELEASE)                                                   02:11:39 4s
Target: x86_64-unknown-linux-gnu

DKIOCEJECT == 536896533
DKIOCEJECT == 0x20006415

显然 Swift 确实允许您使用运行时初始化 static 值(不仅仅是常量/文字!)填充 enum 的值,所以你可以这样:

enum MyIoctrlNumbers {

static let DKIOCEJECT: UInt = getIoctrlNumber( group: "d", n: 21 );
static let ANOTHER : Uint = getIoctrlNumber( group: "e", n: 22 );
}

这很好用:

print( "DKIOCEJECT == "   + String( MyIoctrlNumbers.DKIOCEJECT, radix: 10 ));
print( "DKIOCEJECT == 0x" + String( MyIoctrlNumbers.DKIOCEJECT, radix: 16 ) );

给我这个输出:

Swift version 5.5.1 (swift-5.5.1-RELEASE)                                                   02:13:31 6s
Target: x86_64-unknown-linux-gnu


DKIOCEJECT == 536896533
DKIOCEJECT == 0x20006415

关于swift - 在 Swift 中获取 ioctl 数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69961734/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com