Swift / C互操作,Swift中的结构数据更改不会在C中更新

问题描述

我有一个C结构

struct Test {
  int a;
}

typedef struct Test Test;

在C语言中创建一个指针,

Test* myTestPointer = new test();

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

但是我很难理解为什么以下两段代码在C代码中用a的值来衡量是不相等的?

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

解决方法

将表达式myTestPointer!.pointee(类型为Test)的变量x赋值会导致该结构的副本。

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

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

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