当我通过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
在上述两种情况下,对象分配以相同的方式发生
答案 0 :(得分:5)
事实上,SWIG必须为C / C ++中的库提供一个不同的行为接口。
让我们假设,不是实现cvar
对象,而是简单地使用PyInt
等作为生成模块的属性(这是“普通”C扩展所做的)。
然后,当从python代码中,用户为变量赋值时, new PyInt
对象被分配给该属性,但库使用的原始变量不变,因为模块对象不知道在进行赋值时必须修改C-global变量。
这意味着,从python端用户将看到值更改,C库将不会知道更改,因为全局变量表示的内存位置未更改其值。
为了允许用户以从C / C +库中可见的方式设置值,SWIG必须定义此cvar
对象,在执行赋值时,将值分配给库的封面下的变量,即它改变包含全局变量值的内存位置的内容。
这可能是提供__setattr__
和__getattr__
或__getattribute__
的实现,以便cvar
能够覆盖属性赋值的行为。