Python type confusion

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Python type confusion

Ervin Hegedüs
Hi Swig users,

there is a library, written in C (Hamlib), which has a maitained SWIG code. Python, Perl and Tcl modules can be compiled.

Looks like some functions in Python doesn't work as well - they gives back wrong datatype.

There is a very big C structure, which has two member whom has the type int[MACRO]. Eg:


  int preamp[MAXDBLSTSIZ];   /*!< Preamp list in dB, 0 terminated */
  int attenuator[MAXDBLSTSIZ];       /*!< Preamp list in dB, 0 terminated */

There isn't any typemap/custom function to get this variables - all related code had generated by SWIG.

Here is a code part by SWIG (swig2.0 -python ...):

SWIGINTERN PyObject *_wrap_rig_caps_attenuator_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
  PyObject *resultobj = 0;
  struct rig_caps *arg1 = (struct rig_caps *) 0 ;
  void *argp1 = 0 ;
  int res1 = 0 ;
  PyObject * obj0 = 0 ;
  int *result = 0 ;
 
  if (!PyArg_ParseTuple(args,(char *)"O:rig_caps_attenuator_get",&obj0)) SWIG_fail;
  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_rig_caps, 0 |  0 );
  if (!SWIG_IsOK(res1)) {
    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "rig_caps_attenuator_get" "', argument " "1"" of type '" "struct rig_caps *""'");
  }
  arg1 = (struct rig_caps *)(argp1);
  result = (int *) (int *) ((arg1)->attenuator);
  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_int, 0 |  0 );
  return resultobj;
fail:
  return NULL;
}

When I use the compiled (and installed) Python module, I've got this result:

    ...
    att = my_rig.caps.attenuator
    print att

<Swig Object of type 'rot_reset_t *' at 0x7f14893622d0>

The rot_reset_t is defined in an another C header file, and it has a simple int scalar type... I don't know, how could it be there...

The dictionary of the Python type looks like this:

['__class__', '__cmp__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__hex__', '__init__', '__int__', '__le__', '__long__', '__lt__', '__ne__', '__new__', '__oct__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'acquire', 'append', 'disown', 'next', 'own']


With using of C-API, I can access the integer list items as well.


When I change the type of two members above (attenuator, preamp) to an own type, eg:

typedef int arr_int[MAXDBLSTSIZ];
...
  arr_int preamp;       /*!< Preamp list in dB, 0 terminated */
  arr_int attenuator;   /*!< Preamp list in dB, 0 terminated */

then the SWIG generated code changed to this:

  ...
  arg1 = (struct rig_caps *)(argp1);
  result = (int *) ((arg1)->attenuator);
  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_int, 0 |  0 );
  return resultobj;
  ...

So, the type of result will be (int *), instead of (int *)(int *). But the result in Python is same, not changed.

I've tried to use typemap in swig file:
#ifdef SWIGPYTHON
%typemap(out) int [ANY] {
  int i;
  $result = PyList_New($1_dim0);
  for (i = 0; i < $1_dim0; i++) {
    PyObject *o = PyInt_FromInt((int) $1[i]);
    PyList_SetItem($result,i,o);
  }
}
#endif

but it looks like has no effect, the generated C source file is same as above.


What do I forget? What's wrong with that type and code?


Many thanks for any help, ans sorry for the long mail.


a.




------------------------------------------------------------------------------
Mobile security can be enabling, not merely restricting. Employees who
bring their own devices (BYOD) to work are irked by the imposition of MDM
restrictions. Mobile Device Manager Plus allows you to control only the
apps on BYO-devices by containerizing them, leaving personal data untouched!
https://ad.doubleclick.net/ddm/clk/304595813;131938128;j
_______________________________________________
Swig-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/swig-user
Reply | Threaded
Open this post in threaded view
|

Perl type confusion - was: Python type confusion

Ervin Hegedüs
Hi All,

I could solve my previous problem with Python, the solution was:

%include typemaps.i

#ifdef SWIGPYTHON
%typemap(out) int [ANY] {
  int len,i;
  len = 10;
  $result = PyList_New($1_dim0);
  for (i = 0; i < len; i++) {
    PyList_SetItem($result,i,PyInt_FromLong((long)$1[i]));
  }
}
#endif


But now I would like to solve same problem in Python.

Here's what I try:

#ifdef SWIGPERL
%typemap(out) int [ANY] {
    SV* sv = newSV(0);
    AV* av = (AV *)sv_2mortal((SV *)newAV());
    int i = 0,len = 0;
    len = $1_dim0;

    for (i = 0; i < len ; i++) {
        SV* perlval = newSV(0);
        sv_setiv(perlval, (IV)$1[i]);
        av_push(av, perlval);
    }
    SvSetSV($result, newRV_noinc((SV *)av));
}
#endif

In the C source, there is a global variable:

==%==
typedef int aint[10];
struct my_struct {
    aint ilist;
};

typedef struct my_struct my_struct_t;

my_struct_t m;
==%==

In SWIG file:

==%==
%{

typedef int aint[10];
struct my_struct {
    aint ilist;
};
typedef struct my_struct my_struct_t;
extern double My_variable;
extern my_struct_t m;
%}
==%==

In Python, I can access to "ilist" member like this:

print m.ilist

result will be: [0, 3, 6, ....]


But the Pel code doesn't work. Here is how I try:

==%==
#!/usr/bin/perl

use example1;

my @m = $example1::m->{ilist};
foreach(@m) {
    print $i, "'", $_, "'\n";
    $i=$i+1;
}

==%==

the result will be: "0''" (0 is the $i, empty string is the 1st
member in list).


What em'I missing?



Thanks,


a.


On Wed, May 18, 2016 at 10:17:40PM +0200, Ervin Hegedüs wrote:

> Hi Swig users,
>
> there is a library, written in C (Hamlib), which has a maitained SWIG code.
> Python, Perl and Tcl modules can be compiled.
>
> Looks like some functions in Python doesn't work as well - they gives back
> wrong datatype.
>
> There is a very big C structure, which has two member whom has the type
> int[MACRO]. Eg:
>
>
>   int preamp[MAXDBLSTSIZ];   /*!< Preamp list in dB, 0 terminated */
>   int attenuator[MAXDBLSTSIZ];       /*!< Preamp list in dB, 0 terminated */
>
> There isn't any typemap/custom function to get this variables - all related
> code had generated by SWIG.
>
> Here is a code part by SWIG (swig2.0 -python ...):
>
> SWIGINTERN PyObject *_wrap_rig_caps_attenuator_get(PyObject
> *SWIGUNUSEDPARM(self), PyObject *args) {
>   PyObject *resultobj = 0;
>   struct rig_caps *arg1 = (struct rig_caps *) 0 ;
>   void *argp1 = 0 ;
>   int res1 = 0 ;
>   PyObject * obj0 = 0 ;
>   int *result = 0 ;
>
>   if (!PyArg_ParseTuple(args,(char *)"O:rig_caps_attenuator_get",&obj0))
> SWIG_fail;
>   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_rig_caps, 0 |  0 );
>   if (!SWIG_IsOK(res1)) {
>     SWIG_exception_fail(SWIG_ArgError(res1), "in method '"
> "rig_caps_attenuator_get" "', argument " "1"" of type '" "struct rig_caps
> *""'");
>   }
>   arg1 = (struct rig_caps *)(argp1);
>   result = (int *) (int *) ((arg1)->attenuator);
>   resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_int, 0
> |  0 );
>   return resultobj;
> fail:
>   return NULL;
> }
>
> When I use the compiled (and installed) Python module, I've got this result:
>
>     ...
>     att = my_rig.caps.attenuator
>     print att
>
> <Swig Object of type 'rot_reset_t *' at 0x7f14893622d0>
>
> The rot_reset_t is defined in an another C header file, and it has a simple
> int scalar type... I don't know, how could it be there...
>
> The dictionary of the Python type looks like this:
>
> ['__class__', '__cmp__', '__delattr__', '__doc__', '__eq__', '__format__',
> '__ge__', '__getattribute__', '__gt__', '__hash__', '__hex__', '__init__',
> '__int__', '__le__', '__long__', '__lt__', '__ne__', '__new__', '__oct__',
> '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
> '__str__', '__subclasshook__', 'acquire', 'append', 'disown', 'next', 'own']
>
>
> With using of C-API, I can access the integer list items as well.
>
>
> When I change the type of two members above (attenuator, preamp) to an own
> type, eg:
>
> typedef int arr_int[MAXDBLSTSIZ];
> ...
>   arr_int preamp;       /*!< Preamp list in dB, 0 terminated */
>   arr_int attenuator;   /*!< Preamp list in dB, 0 terminated */
>
> then the SWIG generated code changed to this:
>
>   ...
>   arg1 = (struct rig_caps *)(argp1);
>   result = (int *) ((arg1)->attenuator);
>   resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_int, 0
> |  0 );
>   return resultobj;
>   ...
>
> So, the type of result will be (int *), instead of (int *)(int *). But the
> result in Python is same, not changed.
>
> I've tried to use typemap in swig file:
> #ifdef SWIGPYTHON
> %typemap(out) int [ANY] {
>   int i;
>   $result = PyList_New($1_dim0);
>   for (i = 0; i < $1_dim0; i++) {
>     PyObject *o = PyInt_FromInt((int) $1[i]);
>     PyList_SetItem($result,i,o);
>   }
> }
> #endif
>
> but it looks like has no effect, the generated C source file is same as
> above.
>
>
> What do I forget? What's wrong with that type and code?
>
>
> Many thanks for any help, ans sorry for the long mail.
>
>
> a.

--
I � UTF-8

------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are
consuming the most bandwidth. Provides multi-vendor support for NetFlow,
J-Flow, sFlow and other flows. Make informed decisions using capacity
planning reports. https://ad.doubleclick.net/ddm/clk/305295220;132659582;e
_______________________________________________
Swig-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/swig-user