首页 > 解决方案 > Swift / C 互操作,Swift 中的结构数据更改未在 C 中更新

问题描述

我有一个 C 结构

struct Test {
  int a;
}

typedef struct Test Test;

并在 CI 创建一个指针,

Test* myTestPointer = new Test();

我在 Swift 中获得了 struct 指针myTestPointer,并且我检查了该指针确实指向了 Swift 和 C 中的正确地址。

但是我很难理解为什么以下两段代码不等同a于 C 代码中 back 的值?

let x = myTestPointer
x!.pointee.a = 123     // correctly changes the memory, as reflected back in C code
var x = myTestPointer!.pointee
x.a = 123  // does not reflect change back in C code

标签: cswiftpointersstruct

解决方案


将表达式myTestPointer!.pointee(类型Test)的变量分配给变量x会导致结构的副本。

更改会x.a影响此副本,但不会影响指针指向的副本。

实际上,结构副本确实经常被优化器完全碰撞,但在这种情况下,我认为总是会发生副本,因为指针可以像一个黑盒子一样,可以实现任何方式的外部状态观察/变异。

在任何情况下,您都不应该尝试通过共享状态的突变来在 Swift 和 C 之间(或者坦率地说,在任何软件系统的任何两个组件之间)来回传达状态差异。当然,出于性能原因,有时您需要构建其他通信原语(例如,在进程之间构建消息队列,由底层共享内存区域支持),但一般来说,这种方法正在乞求竞争条件和奇怪的同步困难.


推荐阅读