Swift在Struct中丢失了C语言灵活数组成员的属性?

问题描述 投票:1回答:1

我遇到了和解释中完全相同的问题。此处. 遗憾的是,我不明白到底改了什么来解决这个情况。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。

c swift c99 bridge
1个回答
1
投票

我还没有找到合适的方法来解决这个问题,但为了防止它永远不会被回答,我确实找到了一个变通的方法。我可以访问ret的指针,并通过使用ret->size读取完整的内存,然后从mem_size的大小前进。 我意识到可能有一个正确的解决方案,这个方案可能还是多了一个不必要的步骤(advance),但我还没能想出来。

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)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.