SWIG中的指针
由于C/C++大量的使用指针,因此如何处理指针是swig的一项重要的工作。
SWIG有一个简单规则就是
Everything else is a pointer
即除了基本的类型以外的其他数据类型,swig全部通过指针来处理。大致过程就是将操作C/C++中的结构,类,数组等是通过操作指向这些数据的指针操作,封装成python的数据也是一个包含指针信息的python对象。
C/C++的指针在python中是通过一个特殊的对象来保存的,在python中的变量保存的C/C++的数组以及类对象其实就是保存的这些指针对象,然后封装函数也是操作指针来操作真正的结构和数组等对象。
下面我通过自己写的两个例子来说明:
python操作C的struct
首先是C的源程序,定义vector结构和向量相加的函数
vector.h
1
2
3
4
5
6
7
typedef struct Vector {
double x, y, z;
} Vector;
Vector add(Vector a, Vector b);vector.c
1
2
3
4
5
6
7
8
9
10
11
Vector add(Vector a, Vector b)
{
Vector sum;
sum.x = a.x + b.x;
sum.y = a.y + b.y;
sum.z = a.z + b.z;
return sum;
}函数的实现。
vector.i
1
2
3
4
5
6
7%module vector
%{
%}
%include "vector.h" // 封装结构和函数
这样就可以在生成封装文件并一并编译链接生成最终的模块文件。
可见,封装以后可以向使用类一样使用C结构,对象的类型是一种Swig Object
其中对象中包含了指针的类型和保存的地址的值。
包括按值返回的add
函数也是返回一个”指针对象”。
python中操作C数组
array_test.h
1
2
3
void show_array(int * a, int n);array_test.c
1
2
3
4
5
6
7
8
9
void show_array(int * a, int n)
{
int i;
for (i = 0; i < n; ++i)
printf("%d, ", a[i]);
putchar('\n');
}array_test.i
1
2
3
4
5
6
7
8
9
10
11%module array_test
%{
%}
%inline %{
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // 不仅让swig封装,还要把这个复制到生成的封装文件中
%}
void show_array(int *, int); // 让swig封装这个函数
现在就可以使用swig来生成最终的扩展模块库
可见,在python中操作的array也是通过一个Swig Object
对象。其中放置了指针类型和指针的值。