c - 结构中的 C 灵活数组成员中的 Swift 缺少属性?
问题描述
我遇到了与此处解释的完全相同的问题。不幸的是,我不明白究竟做了什么改变来解决这种情况。OP 是否提示 Swift 灵活数组成员的大小以使其在 Swift 中可见?OP是否修改了C库?我想避免这样做。
我在 Swift 中使用了一个 C 库,它返回一个带有灵活数组成员“mbody”的结构。
typedef struct {
size_t size;
char mbody[];
} msg
在 Swift 中,当返回这个结构时,我可以访问属性“size”,但不能访问属性“mbody”。我已经确认 mbody 设置正确。初始化 C 结构的代码的简化版本如下:
const size_t mem_size = msgcount * MSGBOX_SIZE;
msg* ret = malloc(sizeof(msg) + mem_size);
if (!ret)
return NULL;
ret->size = mem_size;
memcpy(ret->mbody, msgrecord, MSGBOX_SIZE);
为什么 Swift 没有获取 msg->mbody 的大小?它是编译器设置吗?我将其设置为 C99。
解决方案
我还没有找到解决这个问题的正确方法,但如果它从未得到回答,我确实找到了解决方法。我可以访问 ret 的指针并通过使用 ret->size 读取完整的内存,然后推进 mem_size 的大小。我意识到那里可能有一个正确的解决方案,而这个可能还有一个额外的不必要的步骤(提前),但我还想不通。
let size = retPointer.pointee.size
let msgRaw = Data(bytes: retPointer, count: (MemoryLayout<msg>.stride + size))
let msgBody = msgRaw.advanced(by: MemoryLayout<Int>.stride)
相反,我的解决方法并不漂亮但有效。我仍然很感激任何能够展示在 Swift 结构中处理 C 灵活数组成员的正确方法的人。在我的解决方法中,我计算需要多少 msg 对象来创建一个足够长的缓冲区以供正文使用,然后复制到该空间。
let totalmem = (mem_size + MemoryLayout<Int>.stride) / MemoryLayout<msg>.stride
let max = Int(ceil(Double(totalmem)) + 1.0)
withUnsafeMutablePointer(to: &msgObj) { orderPtr in
orderPtr.withMemoryRebound(to: msg.self, capacity: max){ reboundPtr in
let bodyPtr = UnsafeMutableRawPointer(reboundPtr).advanced(by: MemoryLayout<Int>.stride)
let bodyBufferPtr = UnsafeMutableRawBufferPointer(start: bodyPtr, count: mem_size)
body.copyBytes(to: bodyBufferPtr)
}
}
推荐阅读
- azure - ADF - startTime 和 endTime 动态内容 - 本月的第一天和最后一天
- uicollectionview - 如何将页脚视图放在collectionView的底部?
- reactjs - 添加一个
块代码中的组件 - powershell - 警告:此模块中没有名为“positio”的属性,univention ucs 中未设置值
- linux - 如何在 golang 的稀疏文件中寻找漏洞和数据
- python - 按网站上的未知按钮下载 CSV 文件时出现问题
- elixir - 找不到任务“文档”。您指的是 “do” 吗?
- javascript - foreach 中的 Discord.JS addField 不起作用
- python - 在 curve_fit 中使用范围允许 list(range(x,y)) 的“x”值为任意数字,但不能为“y”值
- dart - 如何在flutter dart中像android的“PBEWithMD5AndDES”一样进行加密?