Swift 5.2中未导入大型C数组



我正在尝试导入一个64kb的C数组,该数组旨在作为设备上日志的循环缓冲区。当我试图在Swift中访问这个数组时,我遇到了错误

"logging"类型的值没有成员"data">

为了回答有关桥接的潜在问题,我正在使用导入的C库中的其他类型,这些类型在该模拟代码产生的同一文件中定义。

代码设置如下:

logging.h:

typedef struct _logging {
uint8_t data[64*1024];
} logging;

ReadLog.swift:中

struct ReadLog {
var log: logging = logging()
func read() {
//...Do some stuff...
let char = log.data.0 // <- Error here 'Value of type 'logging' has no member 'data'
}
}

将数据大小更改为256导入了此成员,没有任何问题。(我不知道截止日期是多少(。

处理这个问题的最佳方法是什么?

问题是,C数组作为元组导入Swift,并且元组具有最大arity(例如,请参阅Swift中元组基数的限制(如果有的话(是多少?(。Swift 5中的当前限制似乎是4096个元组元素。

一个可能的解决方法是创建一个C辅助函数,该函数返回一个指向C数组的指针。通过SE-0044作为成员导入功能,可以使其看起来像Swift属性。

您只需在定义logging结构的C头文件中或桥接头文件中添加以下代码:

// Pointer to the data elements:
__attribute__((swift_name("getter:logging.dataPtr(self:)")))
static inline const uint8_t * _Nonnull loggingDataPtr(const logging * _Nonnull log)
{
return log->data;
}

现在您可以通过指针读取Swift代码中的日志数据:

struct ReadLog {
var log = logging()
func read() {
//...Do some stuff...
let char = log.dataPtr[0]
}
}

但请注意,没有数组边界检查,必须确保log.dataPtr仅与数组大小内的索引一起使用。

如果您想从Swift读取并将写入日志结构,则将helper函数更改为

// Pointer to the data elements:
__attribute__((swift_name("getter:logging.dataPtr(self:)")))
static inline uint8_t * _Nonnull loggingDataPtr(logging * _Nonnull log)
{
return log->data;
}

最新更新