Swift/C互操作,Swift中的结构数据更改未更新回C

Swift/C互操作,Swift中的结构数据更改未更新回C,c,swift,pointers,struct,C,Swift,Pointers,Struct,我有一个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 // correct

我有一个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

表达式的赋值
myTestPointer!。指向变量
x
的指针(类型
Test)
会导致结构的副本

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

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


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

C和C++是不同的语言。我认为它一定是这样的。是的,不是理想的,但是我需要这个游戏引擎,它有一个C++核心,在iS/SWIFT和Android /KoTLIN(或者任何其他C/C++语言)之间共享。这是我唯一能看到的编写多平台游戏的方法,同时保持出色的效率/速度。不过,我可能会重新思考,看看是否有一种更安全的方法来更新数据,而不必编写大量setter函数,而不是使用我目前获取结构和直接更新内存的方法(我将要说的每件事都有巨大的警告,因为总是需要衡量和权衡)通常,游戏状态/逻辑足够快,与图形渲染方面相比,它不是主要的瓶颈。事实上,在反应流(观察者/发布者)、通知等方面,你可能能负担得起很多奢侈品。如果你确实想采用变异共享内存方法进行更新,我会在Swift方面将其建模为包含游戏状态指针的结构上的函数。每个fn都会取消指针的指向,并就地编辑。是的,我想这是一个权衡利弊的案例。只要我对内存管理和render/UI线程如何处理我的游戏数据很挑剔,我就可以了。我确实认为写一个Swift版本、一个Kotlin版本和一个其他版本会很好,但我必须在某个地方划清界限。对其中一个的更改意味着我需要更改所有其他的,所以我选择了C/C++路线。我非常喜欢变异共享内存方法,但正如斯威夫特不断提醒我的那样,我最终使用的是不安全的指针。@Pixel如果你使用我提到的“网关”对象,不安全的指针就会隐藏在它令人愉快的外观后面(
movePieceTo(x:y:)
castleQueenSide()
,等等)。您只需要确保引用内存比您的小Swift facade更有效。
var x = myTestPointer!.pointee
x.a = 123  // does not reflect change back in C code