charlesdemacbook-pro:swig Cui$ gcc -shared -c example.c -c example_wrap.c -o example.so -I/Developer/SDKs/MacOSX10.5.sdk/System/Library/Frameworks/Ruby.framework/Versions/1.8/Headers
-c参数必不可少,否则会默认编译成可执行文件,而且出错.
由于是从源码直接编译的,所以不需要ruby extconf.rb
如果用ruby extconf.rb生成makefile,再make,将会报错说找不到符号.
注意问题:
swig -ruby example.i
在example.i文件中,结构体的定义有如下要求:
%{ typedef struct Vector { double x, y; }Vector; %} typedef struct Vector { double x, y; }Vector;
还没看明白为何要在%{%}中定义一遍,然后又在外面定义一遍.
还可以这样做,用include
%module mymodule %{ #include "vector.h" %} %include "vector.h" // Just grab original C header file
C里面可以给结构体直接定义属性,但不能定义方法.
swig是在swig文件中解决的:
%extend Vector { // Attach these functions to struct Vector Vector(double x, double y, double z) { Vector *v; v = (Vector *) malloc(sizeof(Vector)); v->x = x; v->y = y; v->z = z; return v; } ~Vector() { free($self); } double magnitude() { return sqrt($self->x*$self->x+$self->y*$self->y+$self->z*$self->z); } void print() { printf("Vector [%g, %g, %g]\n", $self->x,$self->y,$self->z); } };
然后这么用:
>>> v = Vector(3,4,0) # Create a new vector >>> print v.magnitude() # Print magnitude 5.0 >>> v.print() # Print it out [ 3, 4, 0 ] >>> del v # Destroy it
还可以这么定义:
%module mymodule %{ #include "vector.h" %} typedef struct { double x,y,z; %extend { Vector(double x, double y, double z) { ... } ~Vector() { ... } ... } } Vector;
再来一个:
struct Person { char name[50]; ... }
看到没,Person是个结构体,也是一个类,但swig转换成so之后,不知道如何修改name这个属性,因为它是数组.要像下面这样做:
在swig文件中再添加点:
struct Person { %extend { char *name; } ... } // Specific implementation of set/get functions %{ char *Person_name_get(Person *p) { return p->name; } void Person_name_set(Person *p, char *val) { strncpy(p->name,val,50); } %}
就可以Person.name=这样操作了.
从上面这两个增加的方法可以看到,类和实例方法在swig内部是通过命名规则来维护的,
比如Person_name_set,就是Person.name=,就是指Person类的name=方法.
都是我猜的,嘿嘿.
原来FX不是用Haskell给Ruby做DLL扩展么.
还有谁玩这个?一起玩?