The great merge
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@4141 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
6fcc22a1f8
commit
516036631c
1508 changed files with 125983 additions and 44037 deletions
19
SWIG/Examples/python/libffi/Makefile
Normal file
19
SWIG/Examples/python/libffi/Makefile
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
TOP = ../..
|
||||
SWIG = $(TOP)/../swig
|
||||
SRCS =
|
||||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
|
||||
all::
|
||||
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
|
||||
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' LIBS='-L/usr/local/lib -lffi' python
|
||||
|
||||
static::
|
||||
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
|
||||
TARGET='mypython' INTERFACE='$(INTERFACE)' python_static
|
||||
|
||||
clean::
|
||||
$(MAKE) -f $(TOP)/Makefile python_clean
|
||||
rm -f $(TARGET).py
|
||||
|
||||
check: all
|
||||
176
SWIG/Examples/python/libffi/example.i
Normal file
176
SWIG/Examples/python/libffi/example.i
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
/* File : example.i */
|
||||
%module example
|
||||
|
||||
%{
|
||||
#include <unistd.h>
|
||||
#include <ffi.h>
|
||||
%}
|
||||
|
||||
/* A wrapper for execlp() using libffi to handle an arbitrary
|
||||
number of arguments */
|
||||
|
||||
%typemap(in) (...) {
|
||||
char **argv;
|
||||
int argc;
|
||||
int i;
|
||||
|
||||
argc = PyTuple_Size(varargs);
|
||||
argv = (char **) malloc(sizeof(char *)*(argc+1));
|
||||
for (i = 0; i < argc; i++) {
|
||||
PyObject *o = PyTuple_GetItem(varargs,i);
|
||||
if (!PyString_Check(o)) {
|
||||
PyErr_SetString(PyExc_ValueError,"Expected a string");
|
||||
return NULL;
|
||||
}
|
||||
argv[i] = PyString_AsString(o);
|
||||
}
|
||||
argv[i] = NULL;
|
||||
$1 = (void *) argv;
|
||||
}
|
||||
|
||||
/* Rewrite the function call, using libffi */
|
||||
%feature("action") execlp {
|
||||
int i, vc;
|
||||
ffi_cif cif;
|
||||
ffi_type **types;
|
||||
void **values;
|
||||
char **args;
|
||||
|
||||
vc = PyTuple_Size(varargs);
|
||||
types = (ffi_type **) malloc((vc+3)*sizeof(ffi_type *));
|
||||
values = (void **) malloc((vc+3)*sizeof(void *));
|
||||
args = (char **) arg3;
|
||||
|
||||
/* Set up path parameter */
|
||||
types[0] = &ffi_type_pointer;
|
||||
values[0] = &arg1;
|
||||
|
||||
/* Set up first argument */
|
||||
types[1] = &ffi_type_pointer;
|
||||
values[1] = &arg2;
|
||||
|
||||
/* Set up rest of parameters */
|
||||
for (i = 0; i <= vc; i++) {
|
||||
types[2+i] = &ffi_type_pointer;
|
||||
values[2+i] = &args[i];
|
||||
}
|
||||
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+3,
|
||||
&ffi_type_uint, types) == FFI_OK) {
|
||||
ffi_call(&cif, (void (*)()) execlp, &result, values);
|
||||
} else {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
|
||||
free(types);
|
||||
free(values);
|
||||
free(arg3);
|
||||
return NULL;
|
||||
}
|
||||
free(types);
|
||||
free(values);
|
||||
free(arg3);
|
||||
}
|
||||
|
||||
int execlp(const char *path, const char *arg1, ...);
|
||||
|
||||
|
||||
/* A wrapper for printf() using libffi */
|
||||
|
||||
%{
|
||||
typedef struct {
|
||||
int type;
|
||||
union {
|
||||
int ivalue;
|
||||
double dvalue;
|
||||
void *pvalue;
|
||||
} val;
|
||||
} vtype;
|
||||
enum { VT_INT, VT_DOUBLE, VT_POINTER };
|
||||
%}
|
||||
|
||||
%typemap(in) (const char *fmt, ...) {
|
||||
vtype *argv;
|
||||
int argc;
|
||||
int i;
|
||||
|
||||
$1 = PyString_AsString($input);
|
||||
|
||||
argc = PyTuple_Size(varargs);
|
||||
argv = (vtype *) malloc(argc*sizeof(vtype));
|
||||
for (i = 0; i < argc; i++) {
|
||||
PyObject *o = PyTuple_GetItem(varargs,i);
|
||||
if (PyInt_Check(o)) {
|
||||
argv[i].type = VT_INT;
|
||||
argv[i].val.ivalue = PyInt_AsLong(o);
|
||||
} else if (PyFloat_Check(o)) {
|
||||
argv[i].type = VT_DOUBLE;
|
||||
argv[i].val.dvalue = PyFloat_AsDouble(o);
|
||||
} else if (PyString_Check(o)) {
|
||||
argv[i].type = VT_POINTER;
|
||||
argv[i].val.pvalue = (void *) PyString_AsString(o);
|
||||
} else {
|
||||
PyErr_SetString(PyExc_ValueError,"Unsupported argument type");
|
||||
free(argv);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
$2 = (void *) argv;
|
||||
}
|
||||
|
||||
/* Rewrite the function call, using libffi */
|
||||
%feature("action") printf {
|
||||
int i, vc;
|
||||
ffi_cif cif;
|
||||
ffi_type **types;
|
||||
void **values;
|
||||
vtype *args;
|
||||
|
||||
vc = PyTuple_Size(varargs);
|
||||
types = (ffi_type **) malloc((vc+1)*sizeof(ffi_type *));
|
||||
values = (void **) malloc((vc+1)*sizeof(void *));
|
||||
args = (vtype *) arg2;
|
||||
|
||||
/* Set up fmt parameter */
|
||||
types[0] = &ffi_type_pointer;
|
||||
values[0] = &arg1;
|
||||
|
||||
/* Set up rest of parameters */
|
||||
for (i = 0; i < vc; i++) {
|
||||
switch(args[i].type) {
|
||||
case VT_INT:
|
||||
types[1+i] = &ffi_type_uint;
|
||||
values[1+i] = &args[i].val.ivalue;
|
||||
break;
|
||||
case VT_DOUBLE:
|
||||
types[1+i] = &ffi_type_double;
|
||||
values[1+i] = &args[i].val.dvalue;
|
||||
break;
|
||||
case VT_POINTER:
|
||||
types[1+i] = &ffi_type_pointer;
|
||||
values[1+i] = &args[i].val.pvalue;
|
||||
break;
|
||||
default:
|
||||
abort(); /* Whoa! We're seriously hosed */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+1,
|
||||
&ffi_type_uint, types) == FFI_OK) {
|
||||
ffi_call(&cif, (void (*)()) printf, &result, values);
|
||||
} else {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
|
||||
free(types);
|
||||
free(values);
|
||||
free(args);
|
||||
return NULL;
|
||||
}
|
||||
free(types);
|
||||
free(values);
|
||||
free(args);
|
||||
}
|
||||
|
||||
int printf(const char *fmt, ...);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue