如何在python中实现C / C ++全局变量?

时间:2013-09-24 11:15:23

标签: python swig

当我通过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  

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

1 个答案:

答案 0 :(得分:5)

事实上,SWIG必须为C / C ++中的库提供一个不同的行为接口。

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

这意味着,从python端用户将看到值更改,C库将不会知道更改,因为全局变量表示的内存位置未更改其值。

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

这可能是提供__setattr____getattr____getattribute__的实现,以便cvar能够覆盖属性赋值的行为。