在 Swift 中获取 ioctl 数字
Getting ioctl numbers in Swift
我在这里想要实现的是获取用于弹出磁盘的 ioctl 编号,我已经在我的桥接 Header:
#define DKIOCEJECT _IO('d', 21)
NSUInteger IOEJECT = DKIOCEJECT;
...这确实适用于创建 ioctl
请求,我想做的只是 Swift 而不是必须使用桥接 Header
在 C 中,我通常会放这样的东西来得到一个 ioctl
数字:
#define DKIOCEJECT _IO('d', 21)
上面通常会 return 一个 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
的值(不仅仅是 consts/literals!), 所以你可以这样:
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
我在这里想要实现的是获取用于弹出磁盘的 ioctl 编号,我已经在我的桥接 Header:
#define DKIOCEJECT _IO('d', 21)
NSUInteger IOEJECT = DKIOCEJECT;
...这确实适用于创建 ioctl
请求,我想做的只是 Swift 而不是必须使用桥接 Header
在 C 中,我通常会放这样的东西来得到一个 ioctl
数字:
#define DKIOCEJECT _IO('d', 21)
上面通常会 return 一个 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
的值(不仅仅是 consts/literals!), 所以你可以这样:
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