/
niceSOFT
/
swig
Обзор
Документация
Войти
/
niceSOFT
/
swig
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Examples/python/libffi/example.i
176 строк
4 KB
William S Fulton
[Python] Accept str in the varargs example typemaps
14 часов назад
14 часов назад
edbbe01
Код
Авторство
О чём код?
/* File : example.i */ %module example %{ #ifdef _WIN32 # include <process.h> # define execlp _execlp #else # include <unistd.h> #endif #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 (!PyUnicode_Check(o)) { PyErr_SetString(PyExc_ValueError,"Expected a string"); SWIG_fail; } argv[i] = (char *) PyUnicode_AsUTF8(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 { free(types); free(values); free(arg3); PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!"); SWIG_fail; } 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 = (char *) PyUnicode_AsUTF8($input); argc = PyTuple_Size(varargs); argv = (vtype *) malloc(argc*sizeof(vtype)); for (i = 0; i < argc; i++) { PyObject *o = PyTuple_GetItem(varargs,i); if (PyLong_Check(o)) { argv[i].type = VT_INT; argv[i].val.ivalue = PyLong_AsLong(o); } else if (PyFloat_Check(o)) { argv[i].type = VT_DOUBLE; argv[i].val.dvalue = PyFloat_AsDouble(o); } else if (PyUnicode_Check(o)) { argv[i].type = VT_POINTER; argv[i].val.pvalue = (void *) PyUnicode_AsUTF8(o); } else { free(argv); PyErr_SetString(PyExc_ValueError,"Unsupported argument type"); SWIG_fail; } } $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 { free(types); free(values); free(args); PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!"); SWIG_fail; } free(types); free(values); free(args); } int printf(const char *fmt, ...);