¥È¥Ã¥× º¹Ê¬ °ìÍ÷ ¥½¡¼¥¹ ¸¡º÷ ¥Ø¥ë¥× RSS ¥í¥°¥¤¥ó

BugTrack-¤½¤Î¾¤Î¥á¥â/12

£ÒÈ÷˺Ͽ /¾õÂÖ¶õ´Ö¥â¥Ç¥ê¥ó¥°/donlp2/¤½¤Î¾¤Î¥á¥â

Python ¡Ü SWIG ­¢

  • Åê¹Æ¼Ô¡§ ¤ß¤å
  • ¥«¥Æ¥´¥ê¡§ Python
  • Í¥ÀèÅÙ¡§ ÉáÄÌ
  • ¾õÂÖ¡§ ´°Î»
  • Æü»þ¡§ 2010ǯ01·î03Æü 12»þ37ʬ56ÉÃ

ÆâÍÆ

Makefile

  • ¤³¤ó¤ÊMakefile¤òÍÑ°Õ
CC=gcc
CFLAGS=-O2
includeDir=/usr/include/python2.5

%_wrap.c : %.i
	swig -python $^

%.o : %.c
	$(CC) $(CFLAGS) -c $^ -I $(includeDir)

_%.so : %.o %_wrap.o
	$(CC) -shared $^ -o $@

19.3 ´ðËÜŪ¤ÊC/C++¥é¥Ã¥Ô¥ó¥°¤Î³µÍ×

19.3.2 ´Ø¿ô

  • example.c
int  fact(int n) {
	if (n <= 1) return 1;
	else return n*fact(n-1);
}
  • example.i
%module example
int fact(int n);
  • make¡¢_example.so¤òºî¤ë
$ make _example.so
gcc -O2 -c example.c -I /usr/include/python2.5
swig -python example.i
gcc -O2 -c example_wrap.c -I /usr/include/python2.5
gcc -shared example.o example_wrap.o -o _example.so
/usr/lib/gcc/i486-pc-linux-gnu/4.3.2/../../../../i486-pc-linux-gnu/bin/ld: warni
ng: creating a DT_TEXTREL in object.
  • Æ°ºî
$ python
Python 2.5.4 (r254:67916, Jun  8 2009, 13:35:50)
>>> import example
>>> example.fact(4)
24

19.3.3 Âç°èÊÑ¿ô

  • example.c
double  My_variable  = 3.0;
double density;

/* Compute factorial of n */
int  fact(int n) {
	if (n <= 1) return 1;
	else return n*fact(n-1);
}
  • example.i
/* File : example.i */
%module example
%{
	/* Put headers and other declarations here */
	extern double My_variable;
	extern double density;
%}
extern double My_variable;
extern double density;
int    fact(int);
  • ¡Ö%{¡×¤È¡Ö%}¡×¤Î´Ö¤ËÆþ¤ì¤ë¤Î¤ÈÆþ¤ì¤Ê¤¤¤Î¤È¤Î°ã¤¤¤¬¤Þ¤ÀÎɤ¯¤ï¤«¤é¤Ê¤¤¡¦¡¦¡¦
  • ¡Öextern double My_variable;¡×¤È¡Öextern double density;¡×¤ÏξÊý¤Ë½ñ¤«¤Ê¤¤¤È¡¢¼Â¹Ô»þ¤Ë¥¨¥é¡¼¤¬½Ð¤¿¡¥
  • Æ°ºî
$ python
>>> import example
>>> print example.fact(4)
24
>>> print example.cvar.My_variable
3.0
>>> example.cvar.density
0.0
>>> example.cvar.density = 0.8442
>>> example.cvar.density
0.84419999999999995
>>> example.cvar.density*1.10
0.92862
>>> example.cvar.density = example.cvar.density*1.10
>>> example.cvar.density
0.92862

19.3.4 Äê¿ô¤ÈÎóµó¿ô(enums)

  • example.i¤Ë°Ê²¼¤òÄɲÃ
#define PI 3.14159
#define VERSION "1.0"

%constant int FOO = 42;
%constant const char *path = "/usr/local";
  • Æ°ºî
>>> import example
>>> example.PI
3.1415899999999999
>>> example.VERSION
'1.0'
>>> example.FOO
42
>>> example.path
'/usr/local'
  • ¡Öenum Beverage { ALE, LAGER, STOUT, PILSNER };¡×¤Ï
    • ¡Ú°úÍÑ¡ÛÎóµó¿ô¤ËÂФ·¤Æ¤Ï¡¢Îóµó¤ÎÄêµÁ¤¬É¬¤º¥Ø¥Ã¥À¥Õ¥¡¥¤¥ë¤«¥é¥Ã¥Ñ¡¼¥Õ¥¡¥¤¥ë¤Ë¸½¤ì¤Æ¤¤¤ë¤³¤È¤ò³Îǧ¤¹¤ë¤³¤È -- C¥³¥ó¥Ñ¥¤¥é¤Ë²¿¤âÃΤ餻¤º¤ËSWIG¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹Æâ¤ËÎóµó¿ô¤ò½ñ¤­¹þ¤à¤È¡¢¥é¥Ã¥Ñ¡¼¤Ï¥³¥ó¥Ñ¥¤¥ë¤Ç¤­¤Ê¤¯¤Ê¤ë¤Î¤À¡£

19.3.6 ¹½Â¤ÂÎ

  • example.i¤Ë°Ê²¼¤òÄɲÃ
%inline %{
struct Vector {
	double x,y,z;
};
%}
  • Æ°ºî
>>> import example
>>> v = example.Vector()
>>> v
<example.Vector; proxy of <Swig Object of type 'Vector *' at 0x804df40> >
>>> example.Vector()
<example.Vector; proxy of <Swig Object of type 'Vector *' at 0x80b05b0> >
>>> v.x
0.0
>>> v.y
0.0
>>> v.x = 3.5
>>> v.y = 7.2
>>> print v.x, v.y, v.z
3.5 7.2 0.0

19.7.1 Æþ½ÐÎϥѥé¥á¡¼¥¿

  • example.c¤Ë°Ê²¼¤òÄɲÃ
void add(int x, int y, int *result) {
	*result = x + y;
}
int sub(int *x, int *y) {
	return *x-*y;
}
  • example.i¤Ë°Ê²¼¤òÄɲÃ
%include "typemaps.i"
void add(int, int, int *OUTPUT);
int  sub(int *INPUT, int *INPUT);
  • Æ°ºî
>>> import example
>>> add(3,4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'add' is not defined
>>> example.add(3,4)
7
  • example.i¤Î¤ß¤Ë°Ê²¼¤òÄɲ䷤Ƥâ¤è¤µ¤²
    • inline¤Î¤Û¤¦¤¬¡¢¸å¤Ëµ­½Ò¤µ¤ì¤Æ¤Ê¤¤¤È¤À¤á¤Ã¤Ý¤¤
%include "typemaps.i"
void add(int, int, int *OUTPUT);
int  sub(int *INPUT, int *INPUT);
%inline %{
	void add(int x, int y, int *result) {
		*result = x + y;
	}
	int sub(int *x, int *y) {
		return *x-*y;
	}
%}
  • Æ°ºî
>>> import example
>>> example.add(3,4)
7
>>> example.sub(7,4)
3

19.7.3 ¶­³¦¤Ê¤·CÇÛÎó

  • example.i¤Ë°Ê²¼¤òÄɲÃ
%module example
%{
	¡¦¡¦¡¦
	int sumitems(int *first, int nitems) {
	    int i, sum = 0;
	    for (i = 0; i < nitems; i++) {
	        sum += first[i];
	    }
	    return sum;
	}
%}
¡¦¡¦¡¦
%include "carrays.i"
%array_class(int, intArray);
  • Æ°ºî
>>> import example
>>> a = example.intArray(10000000)
>>> for i in xrange(10000):
...     a[i] = i
...
>>> example.sumitems(a,10000)
49995000

19.9.1 Python¥ê¥¹¥È¤«¤échar **¤Ø¤ÎÊÑ´¹

  • example.i¤Ë°Ê²¼¤òÄɲÃ
// SWIG¤Ëchar **¤òÆÃÊÌ°·¤¤¤¹¤ë¤è¤¦¤ËÃΤ餻¤ë
%typemap(in) char ** {
  /* ¥ê¥¹¥È¤«¤É¤¦¤«¥Á¥§¥Ã¥¯ */
  if (PyList_Check($input)) {
    int size = PyList_Size($input);
    int i = 0;
    $1 = (char **) malloc((size+1)*sizeof(char *));
    for (i = 0; i < size; i++) {
      PyObject *o = PyList_GetItem($input,i);
      if (PyString_Check(o))
	$1[i] = PyString_AsString(PyList_GetItem($input,i));
      else {
	PyErr_SetString(PyExc_TypeError,"list must contain strings");
	free($1);
	return NULL;
      }
    }
    $1[i] = 0;
  } else {
    PyErr_SetString(PyExc_TypeError,"not a list");
    return NULL;
  }
}

// ´Ø¿ô¸Æ¤Ó¤À¤·¤ÎÁ°¤Ëmalloc¤·¤Æ¤¢¤Ã¤¿char **ÇÛÎó¤òÊÒÉÕ¤±¤ë
%typemap(freearg) char ** {
  free((char *) $1);
}

// ¤½¤·¤Æ¥Æ¥¹¥È´Ø¿ô
%inline %{
int print_args(char **argv) {
    int i = 0;
    while (argv[i]) {
         printf("argv[%d] = %s\n", i,argv[i]);
         i++;
    }
    return i;
}
%}
  • Æ°ºî
>>> import example
>>> print_args(["Dave","Mike","Mary","Jane","John"])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'print_args' is not defined
>>> example.print_args(["Dave","Mike","Mary","Jane","John"])
argv[0] = Dave
argv[1] = Mike
argv[2] = Mary
argv[3] = Jane
argv[4] = John
5

¥³¥á¥ó¥È