论坛首页 编程语言技术论坛

Swig编译C/C++代码给Ruby [on Mac]

浏览 2815 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-10-12   最后修改:2009-10-12
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扩展么.
还有谁玩这个?一起玩?
   发表时间:2009-10-12  
CharlesCui 写道
都是我猜的,嘿嘿.

原来FX不是用Haskell给Ruby做DLL扩展么.
还有谁玩这个?一起玩?



是night_stalker玩的,不是FX
0 请登录后投票
   发表时间:2009-10-13  
ray_linn 写道
CharlesCui 写道
都是我猜的,嘿嘿.

原来FX不是用Haskell给Ruby做DLL扩展么.
还有谁玩这个?一起玩?



是night_stalker玩的,不是FX


对了,他俩发帖总是一唱一和的,弄混了.
0 请登录后投票
   发表时间:2009-10-13  
不明白?什么意思?Ruby调c的库?
用ffi不就行了?
0 请登录后投票
   发表时间:2009-10-13  
femto 写道
不明白?什么意思?Ruby调c的库?
用ffi不就行了?


FFI让我很期待,不过等它版本号再高点,我再上手也不迟.
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics