SWIG入门3: C/C++初级特性(一)

2014-11-24 11:06:34 · 作者: · 浏览: 4

SWIG这个项目建立的原因,是为大家提供简洁而又自然的脚本语言接口。什么是简洁而自然呢?它的意思就是C/C++的函数就直接被封装为python的函数,class就被封装成python的class。 这样大家用起来就不会变扭。下面讲一讲一些SWIG所支持的初级的C/C++特性。

1 函数

函数乃是代码复用之源。SWIG对于函数的封装之道至简。封装完之后在python里直接作为模块的方法调用。

1 %module example

2 int fact(int n);


1 >>> import example

2 >>> print example.fact(4)

3 24

4 >>>

2 全局变量

c语言中的各种类型的变量在python中都可以使用。全局变量被放在模块的cvar这个变量中。

01 //file: foo.c

02 #include

03 int bar = 2;

04 float barfloat = 3.14;

05 double bardouble=3.1415926;

06 short barshort=10000;

07 long barlong=200;

08 long long barlonglong=2000000000000ll;

09 unsigned barunsigned = 200;

10

11

12 int barFunc()

13 {

14 printf("this is bar %d.\n"

15 "barfloat %f\n"

16 "bardouble %f\n"

17 "barshort %hd\n"

18 "barlong %ld\n"

19 "barlonglong %lld\n"

20 "barunsigned %u\n"

21 ,bar,barfloat,

22 bardouble,barshort,

23 barlong,barlonglong,

24 barunsigned);

25 return 0;

26 }


01 //file: foo.i

02 %module foo

03 %{

04 extern int bar;

05 extern float barfloat;

06 extern double bardouble;

07 extern short barshort;

08 extern long barlong;

09 extern long long barlonglong;

10 extern unsigned barunsigned;

11 %}

12

13 int bar;

14 float barfloat;

15 double bardouble;

16 short barshort;

17 long barlong;

18 long long barlonglong;

19 unsigned barunsigned;

20 int barFunc();


需要注意的是,全局变量必需在.i文件中extern一下。否则编译foo_wrap.c的时候会报错。

使用的时候直接使用foo.var.xxx就可以了。比如

1 [GCC 4.4.5] on linux2

2 Type "help", "copyright", "credits" or "license" for more information.

3 >>> import foo

4 >>> foo.bar

5 Traceback (most recent call last):

6 File "", line 1, in

7 AttributeError: 'module' object has no attribute 'bar'

8 >>> print foo.cvar.bar

9 2

特别值得注意的是, 每一个类型的数字在python中也会做范围检查,如果赋值超过了该类型的范围,python会抛overflowerror.

1 >>> foo.cvar.barunsigned=-1

2 Traceback (most recent call last):

3 File "", line 1, in

4 OverflowError: in variable 'barunsigned' of type 'unsigned int'

另外,假如修改一个const全局变量,会引发一个segment fault。 所以处理const全局变量的最好方法是使用%immutable 和%mutable。 这两个关键字分别代表只读和可写的变量。

1 %immutable;

2 int barconst;


1 [GCC 4.4.5] on linux2

2 Type "help", "copyright", "credits" or "license" for more information.

3 >>> import foo

4 >>> foo.cvar.barconst=2

5 Traceback (most recent call last):

6 File "", line 1, in

7 AttributeError: Variable barconst is read-only.

8 >>>

这样做只会引发异常,而不会引发更致命的段错误。 %immutable指令会一直有效,直到你显示的使用%mutable指令为止。

假如你觉得cvar这个名字不够酷,你也可以为他换一个别的名字。只要在执行swig时候使用-globals varname 参数。

view sourceprint 1 swig -python -globals variable foo.i

3 SWIG的const变量和枚举变量

除了直接使用C语言模块中定义的变量,在SWIG脚本中,也可以为python脚本定义的const变量和枚举变量。可以用到的技术有#define, enum,%constant。 其中enum枚举变量需要也写进你的xxx_wrap.c代码中去。

1 %{

2 enum People{Man,Woman};

3 %}

4 #define PI 3.1415

5 #define VERSION "1.0"

6

7 enum People{Man,Woman};

8 %constant int barconstant=100;

使用这种变量就不需要通过cvar了。因为这就是Python脚本自身定义的变量,和你的C语言的代码无关。

01 Type "help", "copyright", "credits" or "license" for more information.

02 >>> import foo

03 >>> foo.VERSION

04 '1.0'

05 >>> foo.PI

06 3.1415000000000002

07 >>> foo.Woman

08 1

09 >>> foo.Man

10 0

11 >>> foo.barconstant

12 100


4 指针

因为PYTHON里面并没有指针,所以SWIG只是将指针处理成了一种对象。

1 %module foo

2 FILE* fopen(const char* fname,const cha