diff --git a/SWIG/Examples/test-suite/primitive_types.i b/SWIG/Examples/test-suite/primitive_types.i index 492fed210..efe3df297 100644 --- a/SWIG/Examples/test-suite/primitive_types.i +++ b/SWIG/Examples/test-suite/primitive_types.i @@ -56,6 +56,26 @@ %apply int { enum SWIGTYPE }; + Also note that this test should not only compile, if you run the + program + + grep 'resultobj = SWIG_NewPointerObj' primitive_types_wrap.cxx + + you should get only two calls: + + resultobj = SWIG_NewPointerObj((void *) result, SWIGTYPE_p_Test, 1); + resultobj = SWIG_NewPointerObj((void *) result, SWIGTYPE_p_TestDirector, 1); + + if you get a lot more, some typemap could be not defined. + + The same with + + grep SWIG_ConvertPtr primitive_types_wrap.cxx| egrep -v 'Test' + + you should only get + + #define SWIG_ConvertPtr(obj, pp, type, flags) + */ // @@ -63,8 +83,8 @@ // these nowarn flags. // #pragma SWIG nowarn=451 -#pragma SWIG nowarn=515 -#pragma SWIG nowarn=509 + //#pragma SWIG nowarn=515 + //#pragma SWIG nowarn=509 %{ #include @@ -74,20 +94,32 @@ %feature("director") TestDirector; -// Fake integer class, only visible in C++ %{ + // Integer class, only visible in C++ struct MyInt { char name[5]; int val; MyInt(int v = 0): val(v) { - name[0]='n'; } operator int() const { return val; } }; + // Template primitive type, only visible in C++ + template + struct Param + { + char name[5]; + T val; + + Param(T v = 0): val(v) { + } + + operator T() const { return val; } + }; + typedef char namet[5]; extern namet gbl_namet; namet gbl_namet; @@ -98,6 +130,14 @@ // %apply int { MyInt }; %apply const int& { const MyInt& }; +%apply int { Param }; +%apply char { Param }; +%apply float { Param }; +%apply double { Param }; +%apply const int& { const Param& }; +%apply const char& { const Param& }; +%apply const float& { const Param& }; +%apply const double& { const Param& }; @@ -107,6 +147,7 @@ %apply const int& { const Hello& }; %apply long { pint }; +%apply const long& { const pint& }; // @@ -118,9 +159,11 @@ typedef char namet[5]; typedef char* pchar; + typedef const char* pcharc; typedef int* pint; char* const def_pchar = "hello"; + const char* const def_pcharc = "hija"; const namet def_namet = {'h','o',0, 'l','a'}; @@ -148,9 +191,12 @@ #define def_sizet 1 #define def_hello Hola #define def_myint 1 +#define def_parami 1 +#define def_paramd 1 +#define def_paramc 'c' -%define %test_prim_types_int(macro, pfx) -/* all the primitive types */ +/* types that can be declared as static const class members */ +%define %test_prim_types_stc(macro, pfx) macro(bool, pfx, bool) macro(signed char, pfx, schar) macro(unsigned char, pfx, uchar) @@ -168,14 +214,24 @@ macro(char, pfx, char) %enddef -%define %test_prim_types(macro, pfx) -%test_prim_types_int(macro, pfx) +/* types that can be used to test overloading */ +%define %test_prim_types_ovr(macro, pfx) +%test_prim_types_stc(macro, pfx) macro(pchar, pfx, pchar) +%enddef + +/* all the types */ +%define %test_prim_types(macro, pfx) +%test_prim_types_ovr(macro, pfx) +macro(pcharc, pfx, pcharc) macro(pint, pfx, pint) /* these ones should behave like primitive types too */ -macro(size_t, pfx, sizet) macro(Hello, pfx, hello) macro(MyInt, pfx, myint) +macro(Param, pfx, parami) +macro(Param, pfx, paramd) +macro(Param, pfx, paramc) +macro(size_t, pfx, sizet) %enddef @@ -191,8 +247,6 @@ macro(MyInt, pfx, myint) /* C++ constant declaration */ %define cct_decl(type, pfx, name) const type pfx##_##name = def##_##name; - const type* pfx##_##name##_p = &pfx##_##name; - const type& pfx##_##name##_r = pfx##_##name; %enddef /* C++ static constant declaration */ @@ -233,6 +287,7 @@ macro(MyInt, pfx, myint) void var_init() { var_pchar = 0; + var_pcharc = 0; var_pint = 0; var_namet[0] = 'h'; } @@ -255,9 +310,10 @@ macro(MyInt, pfx, myint) /* check a function call */ %define call_check(type, pfx, name) - if (pfx##_##name(def_##name) != def_##name) { + type pfx##_##tmp##name = def_##name; + if (pfx##_##name(pfx##_##tmp##name) != def_##name) { std::ostringstream a; std::ostringstream b; - a << pfx##_##name(def_##name); + a << pfx##_##name(pfx##_##tmp##name); b << def_##name; if (a.str() != b.str()) { std::cout << "failing in pfx""_""name : " @@ -275,10 +331,11 @@ macro(MyInt, pfx, myint) /* function passing by value */ %define ovr_decl(type, pfx, name) - int pfx##_##val(type x) { return 1; } - int pfx##_##ref(const type& x) { return 1; } + virtual int pfx##_##val(type x) { return 1; } + virtual int pfx##_##ref(const type& x) { return 1; } %enddef + #ifdef SWIGPYTHON %apply (char *STRING, int LENGTH) { (const char *str, size_t len) } %apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) } @@ -288,13 +345,34 @@ macro(MyInt, pfx, myint) struct Test { Test() - : var_pchar(0), var_pint(0) + : var_pchar(0), var_pcharc(0), var_pint(0) { } - %test_prim_types_int(stc_decl, stc); + %test_prim_types_stc(stc_decl, stc); %test_prim_types(var_decl, var); var_decl(namet, var, namet); + + const char* val_namet(namet x) throw(namet) + { + return x; + } + + const char* val_cnamet(const namet x) throw(namet) + { + return x; + } + +#if 0 + /* I have no idea how to define a typemap for + const namet&, where namet is a char[ANY] array */ + const namet& ref_namet(const namet& x) throw(namet) + { + return x; + } +#endif + + %test_prim_types(val_decl, val); %test_prim_types(ref_decl, ref); @@ -307,13 +385,13 @@ macro(MyInt, pfx, myint) int v_check() { - %test_prim_types_int(var_check, stc); + %test_prim_types_stc(var_check, stc); %test_prim_types(var_check, var); var_check(namet, var, namet); return 1; } - %test_prim_types_int(ovr_decl, ovr); + %test_prim_types_ovr(ovr_decl, ovr); int strlen(const char *str, size_t len) { @@ -328,24 +406,44 @@ macro(MyInt, pfx, myint) const char* mainv(size_t argc, const char **argv, int idx) { return argv[idx]; - } - + } }; struct TestDirector { TestDirector() - : var_pchar(0), var_pint(0) + : var_pchar(0), var_pcharc(0), var_pint(0) { } + virtual ~TestDirector() { var_namet[0]='h'; } - %test_prim_types_int(stc_decl, stc); + virtual const char* vval_namet(namet x) throw(namet) + { + return x; + } + + virtual const char* vval_cnamet(const namet x) throw(namet) + { + return x; + } + +#if 0 + /* I have no idea how to define a typemap for + const namet&, where namet is a char[ANY] array */ + virtual const namet& vref_namet(const namet& x) throw(namet) + { + return x; + } +#endif + + + %test_prim_types_stc(stc_decl, stc); %test_prim_types(var_decl, var); var_decl(namet, var, namet); @@ -367,13 +465,12 @@ macro(MyInt, pfx, myint) int v_check() { - %test_prim_types_int(var_check, stc); + %test_prim_types_stc(var_check, stc); %test_prim_types(var_check, var); return 1; } - - %test_prim_types_int(ovr_decl, ovr); + %test_prim_types_ovr(ovr_decl, ovr); }; diff --git a/SWIG/Examples/test-suite/python/primitive_types_runme.py b/SWIG/Examples/test-suite/python/primitive_types_runme.py index 60c378638..1b32b1d5e 100644 --- a/SWIG/Examples/test-suite/python/primitive_types_runme.py +++ b/SWIG/Examples/test-suite/python/primitive_types_runme.py @@ -18,11 +18,15 @@ cvar.var_float = sct_float cvar.var_double = sct_double cvar.var_char = sct_char cvar.var_pchar = sct_pchar +cvar.var_pcharc = sct_pcharc cvar.var_pint = sct_pint cvar.var_sizet = sct_sizet cvar.var_hello = sct_hello cvar.var_myint = sct_myint cvar.var_namet = def_namet +cvar.var_parami = sct_parami +cvar.var_paramd = sct_paramd +cvar.var_paramc = sct_paramc v_check() @@ -46,6 +50,7 @@ if cvar.var_float != cct_float: pyerror("float", cvar.var_float, cct_float) if cvar.var_double != cct_double: pyerror("double", cvar.var_double, cct_double) if cvar.var_char != cct_char: pyerror("char", cvar.var_char, cct_char) if cvar.var_pchar != cct_pchar: pyerror("pchar", cvar.var_pchar, cct_pchar) +if cvar.var_pcharc != cct_pcharc: pyerror("pchar", cvar.var_pcharc, cct_pcharc) if cvar.var_pint != cct_pint: pyerror("pint", cvar.var_pint, cct_pint) if cvar.var_sizet != cct_sizet: pyerror("sizet", cvar.var_sizet, cct_sizet) if cvar.var_hello != cct_hello: pyerror("hello", cvar.var_hello, cct_hello) @@ -74,6 +79,7 @@ class PyTest (TestDirector): def vval_double(self, x): return self.ident(x) def vval_char(self, x): return self.ident(x) def vval_pchar(self, x): return self.ident(x) + def vval_pcharc(self, x): return self.ident(x) def vval_pint(self, x): return self.ident(x) def vval_sizet(self, x): return self.ident(x) def vval_hello(self, x): return self.ident(x) @@ -94,6 +100,7 @@ class PyTest (TestDirector): def vref_double(self, x): return self.ident(x) def vref_char(self, x): return self.ident(x) def vref_pchar(self, x): return self.ident(x) + def vref_pcharc(self, x): return self.ident(x) def vref_pint(self, x): return self.ident(x) def vref_sizet(self, x): return self.ident(x) def vref_hello(self, x): return self.ident(x) @@ -125,11 +132,15 @@ p.var_float = p.stc_float p.var_double = p.stc_double p.var_char = p.stc_char p.var_pchar = sct_pchar +p.var_pcharc = sct_pcharc p.var_pint = sct_pint p.var_sizet = sct_sizet p.var_hello = sct_hello p.var_myint = sct_myint p.var_namet = def_namet +p.var_parami = sct_parami +p.var_paramd = sct_paramd +p.var_paramc = sct_paramc p.v_check() @@ -149,11 +160,15 @@ t.var_float = t.stc_float t.var_double = t.stc_double t.var_char = t.stc_char t.var_pchar = sct_pchar +t.var_pcharc = sct_pcharc t.var_pint = sct_pint t.var_sizet = sct_sizet t.var_hello = sct_hello t.var_myint = sct_myint t.var_namet = def_namet +t.var_parami = sct_parami +t.var_paramd = sct_paramd +t.var_paramc = sct_paramc t.v_check() @@ -175,7 +190,7 @@ if t.var_namet != 'holac': t.var_namet = 'hol' -if t.var_namet != 'hol': +if t.var_namet != 'hol\0\0': print "bad namet", t.var_namet raise RuntimeError @@ -190,3 +205,40 @@ if t.mainv(targs,1) != 'hola': if t.strlen('hile') != 4: raise RuntimeError, "bad string typemap" + + + +cvar.var_char = '\0' +if cvar.var_char != '\0': + raise RuntimeError, "bad char '0' case" + +cvar.var_char = 0 +if cvar.var_char != '\0': + raise RuntimeError, "bad char '0' case" + +cvar.var_namet = '\0' +if cvar.var_namet != '\0\0\0\0\0': + raise RuntimeError, "bad char '\0' case" + +cvar.var_namet = '' +if cvar.var_namet != '\0\0\0\0\0': + raise RuntimeError, "bad char empty case" + +cvar.var_pchar = None +if cvar.var_pchar != None: + raise RuntimeError, "bad None case" + +cvar.var_pchar = '' +if cvar.var_pchar != '': + raise RuntimeError, "bad char empty case" + +cvar.var_pcharc = None +if cvar.var_pcharc != None: + raise RuntimeError, "bad None case" + +cvar.var_pcharc = '' +if cvar.var_pcharc != '': + raise RuntimeError, "bad char empty case" + + + diff --git a/SWIG/Lib/python/pyrun.swg b/SWIG/Lib/python/pyrun.swg index 7896a4bbd..8e106b648 100644 --- a/SWIG/Lib/python/pyrun.swg +++ b/SWIG/Lib/python/pyrun.swg @@ -148,15 +148,33 @@ SPyObj_AsFloat(PyObject *obj) { return (float) value; } +SWIG_STATIC_INLINE void +SPyObj_AsCharPtrAndSize(PyObject *obj, char** cptr, int* len) { + if (obj != Py_None) { + PyString_AsStringAndSize(obj, cptr, len); + } else { + *cptr = 0; *len = 0; + } +} + SWIG_STATIC_INLINE char SPyObj_AsChar(PyObject *obj) { - char c = (PyString_Check(obj) && PyString_Size(obj) == 1) ? - PyString_AsString(obj)[0] - : (char) SPyObj_AsLongInRange(obj, CHAR_MIN, CHAR_MAX); - if (PyErr_Occurred()) { - PyErr_Clear(); - PyErr_SetString(PyExc_TypeError, "a char is required"); - } + char c; + if (PyString_Check(obj)) { + char* cptr; int len; + SPyObj_AsCharPtrAndSize(obj, &cptr, &len); + if (len == 1) { + c = cptr[0]; + } else { + PyErr_SetString(PyExc_OverflowError, "a char is required"); + } + } else { + c = (char) SPyObj_AsLongInRange(obj, CHAR_MIN, CHAR_MAX); + if (PyErr_Occurred()) { + PyErr_Clear(); + PyErr_SetString(PyExc_TypeError, "a char is required"); + } + } return c; } @@ -165,41 +183,57 @@ SPyObj_FromChar(char c) { return PyString_FromStringAndSize(&c,1); } -SWIG_STATIC_INLINE PyObject * -SPyObj_FromCharPtr(const char* cptr) { - return cptr ? PyString_FromString(cptr) : Py_BuildValue((char*)""); +SWIG_STATIC_INLINE char* +SPyObj_AsCharPtr(PyObject *obj) { + return (obj != Py_None) ? PyString_AsString(obj) : (char*) 0; } -/* - these two routines allows char[ANY] with '0' chars inside, ie: - - const char def_namet[5] = {'h','o',0, 'l','a'}; - - is not truncated to "ho". - */ +SWIG_STATIC_INLINE PyObject * +SPyObj_FromCharPtr(const char* cptr) { + if (cptr) { + return PyString_FromString(cptr); + } else { + Py_INCREF(Py_None); + return Py_None; + } +} + +SWIG_STATIC_INLINE char* +SPyObj_AsNewCharPtr(PyObject *obj) { + char *res = 0; + char* cptr; int len; + SPyObj_AsCharPtrAndSize(obj, &cptr, &len); + if (!PyErr_Occurred() && cptr) { + size_t size = (len && !(cptr[len - 1])) ? len : len + 1; +#ifdef __cplusplus + res = new char[size]; +#else + res = malloc(size); +#endif + if (len) memcpy(res, cptr, len); + res[size-1] = 0; + } + return res; +} SWIG_STATIC_INLINE PyObject * -SPyObj_FromCharArray(const char* carray, int len) { +SPyObj_FromCharArray(const char* carray, int size) { /* checking the effective size backward */ - for (; len && (carray[len - 1] == 0); --len); - - return PyString_FromStringAndSize(carray, len); + //for (; size && (carray[size - 1] == 0); --size); + return PyString_FromStringAndSize(carray, size); } SWIG_STATIC_INLINE void SPyObj_AsCharArray(PyObject *obj, char* carray, int size) { - int len = size; - char* buf; - PyString_AsStringAndSize(obj, &buf, &len); + char* cptr; int len; + SPyObj_AsCharPtrAndSize(obj, &cptr, &len); if (!PyErr_Occurred()) { if (len > size) { PyErr_SetObject(PyExc_TypeError, PyString_FromFormat("a string of maximum size %d is required", size)); } else { - memcpy(carray, buf, len); - /* pad the string with zero chars if needed */ - if (len < size) - memset(carray + len, 0, size - len); + if (len) memcpy(carray, cptr, len); + if (len < size) memset(carray + len, 0, size - len); } } } diff --git a/SWIG/Lib/python/python.swg b/SWIG/Lib/python/python.swg index 231f40117..9cc50fd0e 100644 --- a/SWIG/Lib/python/python.swg +++ b/SWIG/Lib/python/python.swg @@ -23,6 +23,7 @@ /* auxiliar macros for char array alloc/dealloc */ + #ifdef __cplusplus %define %swig_new_carray(size) new char[(size)] %enddef @@ -35,7 +36,6 @@ %enddef #endif - /* ----------------------------------------------------------------------------- * standard typemaps * ----------------------------------------------------------------------------- */ @@ -139,14 +139,22 @@ %typemap(in) SWIGTYPE (CLASS::*) "if ((SWIG_ConvertPacked($input, (void *) &$1, sizeof($1_type), $1_descriptor,SWIG_POINTER_EXCEPTION)) == -1) SWIG_fail;"; /* The char* and char [ANY] case */ -%typemap(in) char * +%typemap(in) char *, char const*, char *const, char const *const { - $1 = PyString_AsString($input); + $1 = SPyObj_AsCharPtr($input); if (PyErr_Occurred()) SWIG_fail; } -%typemap(in) char [ANY] (char temp[$1_dim0]) +%typemap(in) char const*&, char *const&, char const *const & +{ + $*ltype temp = SPyObj_AsCharPtr($input); + $1 = &temp; + if (PyErr_Occurred()) SWIG_fail; +} + +%typemap(in) char [ANY], const char [ANY] { + char temp[$1_dim0]; SPyObj_AsCharArray($input, temp, $1_dim0); if (PyErr_Occurred()) SWIG_fail; $1 = temp; @@ -182,9 +190,12 @@ %typemap(out) void "Py_INCREF(Py_None); $result = Py_None;"; /* Special typemap for character array return values */ -%typemap(out) char *, const char * "$result = SPyObj_FromCharPtr((const char*)$1);"; +%typemap(out) char*, char const*, char *const, char const *const, + char *const &, char const* &, char const *const & + "$result = SPyObj_FromCharPtr((const char*)$1);"; -%typemap(out) char [ANY], const char [ANY] "$result = SPyObj_FromCharArray((const char*)$1, $1_dim0);"; +%typemap(out) char [ANY], const char [ANY] + "$result = SPyObj_FromCharArray((const char*)$1, $1_dim0);"; /* Primitive types--return by value */ %typemap(out) SWIGTYPE @@ -222,30 +233,27 @@ %expand_primitives_as(PY_VARIN_TYPEMAP); -/* A strings */ +/* char* and char[ANY] */ %typemap(varin) char * { - char *temp = (char *) PyString_AsString($input); + char *cptr = SPyObj_AsNewCharPtr($input); if (PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); return 1; } - if ($1) %swig_del_carray($1); - $1 = ($type) %swig_new_carray(strlen(temp)+1); - strcpy((char*)$1,temp); + if ($1) + %swig_del_carray($1); + $1 = cptr; } %typemap(varin,warning="451:Setting const char * variable may leak memory") const char * { - char *temp = (char *) PyString_AsString($input); + char *cptr = SPyObj_AsNewCharPtr($input); if (PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); return 1; } - $1 = ($type) %swig_new_carray(strlen(temp)+1); - strcpy((char*)$1,temp); + $1 = cptr; } - -/* here we need no temp, the variable provide the memory */ %typemap(varin) char [ANY] { SPyObj_AsCharArray($input, $1, $1_dim0); if (PyErr_Occurred()) { @@ -357,7 +365,7 @@ /* Pointers, arrays, objects */ -%typemap(consttab) char *, const char * +%typemap(consttab) char *, char const*, char * const, char const* const { SWIG_PY_STRING, (char*)"$symname", 0, 0, (void *)$value, 0} %typemap(consttab) char [ANY], const char [ANY] @@ -395,16 +403,20 @@ /* Special typemap for character array return values */ -%typemap(directorin) char*, const char * "$input = SPyObj_FromCharPtr((const char*)$1_name);"; +%typemap(directorin) char *, char const*, char *const, char const *const, + char const *&, char *const &, char const *const & + "$input = SPyObj_FromCharPtr((const char*)$1_name);"; -%typemap(directorin) char [ANY], const char [ANY] "$input = SPyObj_FromCharArray((const char*)$1_name, $1_dim0);"; + +%typemap(directorin) char [ANY], const char [ANY] + "$input = SPyObj_FromCharArray((const char*)$1_name, $1_dim0);"; /* --- directorout typemaps --- */ %define PY_DIRECTOROUT_TYPEMAP(Type, pyobj_as) %typemap(directorargout) Type *DIRECTOROUT - "*$result = ($ltype) pyobj_as($input); + "*$result = ($basetype) pyobj_as($input); if (PyErr_Occurred()) throw Swig::DirectorTypeMismatchException(\"Error converting Python object using pyobj_as\");"; %typemap(directorout) Type "$result = ($ltype) pyobj_as($input); @@ -419,14 +431,22 @@ %expand_primitives_as(PY_DIRECTOROUT_TYPEMAP); /* Char pointer and arrays */ -%typemap(directorout) char * { - $result = PyString_AsString($input); +%typemap(directorout) char *, char const*, char *const, char const* const { + $result = SPyObj_AsCharPtr($input); if (PyErr_Occurred()) { Swig::DirectorTypeMismatchException("Error converting Python object into char*"); } } -%typemap(directorout) char [ANY] (char temp[$result_dim0]) { +%typemap(directorout) char const *&, char *const &,char const *const & { + $*ltype temp = SPyObj_AsCharPtr($input); + $result = &temp; + if (PyErr_Occurred()) { + Swig::DirectorTypeMismatchException("Error converting Python object into char*"); + } +} + +%typemap(directorout) char [ANY], const char[ANY] (char temp[$result_dim0]) { SPyObj_AsCharArray($input, temp, $result_dim0); if (PyErr_Occurred()) { Swig::DirectorTypeMismatchException("Error converting Python object into char[$result_dim0]"); @@ -477,12 +497,14 @@ PY_TYPECHECK_TYPEMAP(DOUBLE, double, SPyObj_AsDouble); PY_TYPECHECK_TYPEMAP(CHAR, char, SPyObj_AsChar); -%typecheck(SWIG_TYPECHECK_STRING) char * +%typecheck(SWIG_TYPECHECK_STRING) + char *, char const*, char *const, char const *const, + char const*&, char *const&, char const *const & { - $1 = PyString_Check($input) ? 1 : 0; + $1 = (($input == Py_None) || (PyString_Check($input))); } -%typecheck(SWIG_TYPECHECK_STRING) char [ANY] +%typecheck(SWIG_TYPECHECK_STRING) char [ANY], const char[ANY] { $1 = (PyString_Check($input) && (PyString_Size($input) <= $input_dim0)) ? 1 : 0; @@ -534,7 +556,7 @@ PY_TYPECHECK_TYPEMAP(CHAR, char, SPyObj_AsChar); %expand_primitives_from(PY_THROWS_TYPEMAP); -%typemap(throws) char *, const char * { +%typemap(throws) char *, char const*, char * const, char const* const { PyErr_SetObject(PyExc_RuntimeError, SPyObj_FromCharPtr((const char*)$1)); SWIG_fail; } @@ -616,9 +638,14 @@ PY_TYPECHECK_TYPEMAP(CHAR, char, SPyObj_AsChar); * --- String & length --- * ------------------------------------------------------------ */ -%typemap(in) (char *STRING, int LENGTH) { - $1 = ($1_ltype) PyString_AsString($input); - $2 = ($2_ltype) PyString_Size($input); +%typemap(in) (char *STRING, int LENGTH) (char *buf, int len) { + SPyObj_AsCharPtrAndSize($input, &buf, &len); + if (PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError,"a string is expected"); + SWIG_fail; + } + $1 = ($1_ltype) buf; + $2 = ($2_ltype) len; } /* ------------------------------------------------------------ @@ -636,7 +663,7 @@ PY_TYPECHECK_TYPEMAP(CHAR, char, SPyObj_AsChar); for (; i < size; ++i) { PyObject *obj = list ? PyList_GetItem($input,i) : PyTuple_GetItem($input,i); - $2[i] = PyString_AsString(obj); + $2[i] = SPyObj_AsCharPtr(obj); if (PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError,"list must contain strings only"); SWIG_fail; @@ -650,7 +677,8 @@ PY_TYPECHECK_TYPEMAP(CHAR, char, SPyObj_AsChar); } %typemap(freearg) (int ARGC, char **ARGV) { - if ($2) %swig_del_carray($2); + if ($2) + %swig_del_carray($2); }