2

当我阅读 SWIG 文档时,我通过了这些线路..

SWIG 完全支持 C/C++ 全局变量。但是,由于 Python 赋值的工作方式,底层机制与您可能预期的有所不同。当您在 Python 中键入以下内容时,
a = 3.4
“a”将成为包含值 3.4 的对象的名称。如果您稍后键入
b = a,
则“a”和“b”都是包含值 3.4 的对象的名称。因此,只有一个对象包含 3.4,并且“a”和“b”都是引用它的名称。这与 C 完全不同,其中变量名称指的是存储值的内存位置(并且赋值将数据复制到该位置)。因此,没有直接的方法将 C 中的变量赋值映射到 Python 中的变量赋值。
为了提供对 C 全局变量的访问,SWIG 创建了一个名为“cvar”的特殊对象,该对象被添加到每个 SWIG 生成的模块中。然后将全局变量作为该对象的属性进行访问。

我的问题是以上述方式实施的需要是什么。即使我们以上述方式实现对象属性也实现为对象。

请看下面的python代码片段

a = 10  
b = a  
a is b  
True  

class sample: 
    pass   

obj = sample()  
obj.a = 10  
obj.b = obj.a  
obj.a is obj.b  
True  

在上述两种情况下,对象分配都以相同的方式发生

4

1 回答 1

5

这完全是因为 SWIG 必须为 C/C++ 中的库提供一个接口,该接口的行为不同。

让我们假设cvarSWIG 没有实现对象,而是简单地使用PyInts 等作为生成模块的属性(这是“普通”C 扩展所做的)。然后,当从 python 代码中,用户为变量赋值时,一个 PyInt对象被分配给该属性,但库使用的原始变量没有改变,因为模块对象不知道它必须修改 C 全局做赋值时的变量。

这意味着,虽然从 python 端用户将看到值更改,但 C 库不会意识到更改,因为由全局变量表示的内存位置没有更改其值。

为了允许用户以从 C/C+ 库中可见的方式设置值,SWIG 必须定义这个cvar对象,该对象在执行赋值时,将值赋给库的变量,即它改变包含全局变量值的内存位置的内容。

这可能是通过提供__setattr__and __getattr__or的实现来完成的__getattribute__,以便cvar能够覆盖分配给属性的行为。

于 2013-09-24T11:42:00.747 回答