【问题标题】:C struct instance is missing members after copying it to Swift将 C 结构实例复制到 Swift 后缺少成员
【发布时间】:2017-10-04 15:05:37
【问题描述】:

我通过 Swift 中的包装器使用 C 的 inotify 库。我们的想法是提供一个 Swift 包管理器 库,在 Linux 中提供基本的文件系统事件支持。

几乎一切正常。除了这里,我似乎无法复制inotify_event 成员name

let bufferLength = Int(MemoryLayout<inotify_event>.size + NAME_MAX + 1)
let buffer = UnsafeMutablePointer<CChar>.allocate(capacity: bufferLength)

var fileSystemEvent : FileSystemEvent?
var currentIndex: Int = 0
let readLength = read(Int32(self.fileDescriptor), buffer, bufferLength)

while currentIndex < readLength {
  var event = withUnsafePointer(to: &buffer[currentIndex]) {
    return $0.withMemoryRebound(to: inotify_event.self, capacity: 1) {
      return $0.pointee
    }
  }
  if event.len > 0 {
     fileSystemEvent = FileSystemEvent(
       watchDescriptor: WatchDescriptor(event.wd),
       name: "", //String(cString: event.name),
       mask: event.mask,
       cookie: event.cookie,
       length: event.len
     )
  }
  currentIndex += MemoryLayout<inotify_event>.stride + Int(event.len)
}

我想做:

name: String(cString: event.name),但是然后编译器会抛出错误:

           `value of type 'inotify_event' has no member 'name'`

我找不到任何线索说明为什么会发生这种情况,或者我如何访问name 成员。这是inotify.h中的结构声明:

/*
 * struct inotify_event - structure read from the inotify device for each event
 *
 * When you are watching a directory, you will receive the filename for events
 * such as IN_CREATE, IN_DELETE, IN_OPEN, IN_CLOSE, ..., relative to the wd.
 */
struct inotify_event {
    __s32       wd;     /* watch descriptor */
    __u32       mask;       /* watch mask */
    __u32       cookie;     /* cookie to synchronize two events */
    __u32       len;        /* length (including nulls) of name */
    char        name[0];    /* stub for possible name */
};

这是怎么回事?

在此先感谢 :)

PS:here's my full project,如果您需要更多信息。

【问题讨论】:

  • 您能否在源示例中包含来自“.h”文件的 inotify_event 结构的声明?
  • 您最好编辑您的问题并将inotify_event 的定义包含在其中。并非所有读者都尝试进入链接,结构的定义是您问题的关键信息。
  • 谢谢!我会的:)
  • @felix91gr 在我的 repo 的 fork 上做得很好!我自己偶然发现了这个问题,然后就这样离开了。

标签: c swift linux struct


【解决方案1】:

name 字段定义为长度为零的数组:

char        name[0];    /* stub for possible name */

那些不是 导入 Swift。一个可能的解决方案是计算偏移量 接收缓冲区中名称字符串的开头:

 fileSystemEvent = FileSystemEvent(
   watchDescriptor: WatchDescriptor(event.wd),
   name: String(cString: buffer + currentIndex + MemoryLayout<inotify_event>.size),
   mask: event.mask,
   cookie: event.cookie,
   length: event.len)

【讨论】:

  • @martin-r 你能告诉我关于零长度数组没有被快速导入的文档吗?我正在尝试修改我的 inotify 包装器,以便将名称作为 swift 结构的可选属性进行访问,并且我正在尽我所能了解 swift c interop
猜你喜欢
  • 2014-05-28
  • 2021-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-03
  • 2016-08-04
  • 1970-01-01
  • 2010-10-03
相关资源
最近更新 更多