Favicon

Declaring pointers to pointers C->Python

Hi,

I am trying to use a pointer to a pointer in Python but I cannot seem to work out the correct syntax, the declaration for the C functions is:

typedef struct _GroupList
{
        uint32_t cnt;
        char *name[1];
} GroupList;

int getGroupList(GroupList **myGroupList);

It's a supplied system call so I cannot change the argument call. In python I do:

import example
GroupList = example.GroupList()

print GroupList
example.getGroupList( GroupList )

Which results in:

<example.GroupList; proxy of <Swig Object of type 'GroupList *' at 0x81679b0> >
Traceback (most recent call last):
  File "test.py", line 7, in <module>
    example.getGroupList( GroupList )
TypeError: in method 'getGroupList', argument 1 of type 'GroupList **'

I just cannot work out how to get a pointer to a pointer rather than just a pointer (and I do understand why I just get a pointer) - any help would be most appreciated.

Many Thanks,

Paul Griffiths
------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d
_______________________________________________
Swig-user mailing list
Swig-user <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/swig-user
Bob Hood | 1 Feb 17:38
Picon
Gravatar

Re: Declaring pointers to pointers C->Python

On 2/1/2012 7:09 AM, Paul Griffiths-Todd wrote:
Hi,

I am trying to use a pointer to a pointer in Python but I cannot seem to work out the correct syntax, the declaration for the C functions is:

typedef struct _GroupList
{
        uint32_t cnt;
        char *name[1];
} GroupList;

int getGroupList(GroupList **myGroupList);

It's a supplied system call so I cannot change the argument call. In python I do:

import example
GroupList = example.GroupList()

print GroupList
example.getGroupList( GroupList )

Which results in:

<example.GroupList; proxy of <Swig Object of type 'GroupList *' at 0x81679b0> >
Traceback (most recent call last):
  File "test.py", line 7, in <module>
    example.getGroupList( GroupList )
TypeError: in method 'getGroupList', argument 1 of type 'GroupList **'

I just cannot work out how to get a pointer to a pointer rather than just a pointer (and I do understand why I just get a pointer) - any help would be most appreciated.

Hi, Paul.

Your argument 'myGroupList' to getGroupList() is an "out" parameter, meaning you're expecting the function to set a value into it for return to the caller.  In order to handle "out" parameters, you have to declare an "argout" typemap.  For example, in your particular case, something like the following in your interface file:

    %typemap(argout) GroupList **myGroupList {
        PyObject *o, *o2, *o3;
        // call a function that will construct a
        // Python sequence from the list pointed
        // to by *myGroupList
        o = grouplist_to_python_sequence(*$1);
        if ((!$result) || ($result == Py_None))
            $result = o;
        else
        {
            if(!PyTuple_Check($result))
            {
                PyObject *o2 = $result;
                $result = PyTuple_New(1);
                PyTuple_SetItem($result, 0, o2);
            }
            o3 = PyTuple_New(1);
            PyTuple_SetItem(o3, 0, o);
            o2 = $result;
            $result = PySequence_Concat(o2, o3);
            Py_DECREF(o2);
            Py_DECREF(o3);
        }
    }

    %typemap(in,numinputs=0) GroupList **myGroupList (GroupList *temp) {
        temp = 0;
        $1 = &temp;
    }

You have to understand that, in Python, you cannot provide a "pointer object" to a function call and expect it to be manipulated in place.  Instead, you must handle each "argout" argument to an underlying C++ function as a return value.  That's what the "argout" typemap above does for you.  (It is a bit complex because you're also returning a value from the function.)

So, with this "argout" typemap in place (and a proper definition of grouplist_to_python_sequence()), you would then access the information in the Python environment thusly:

    import example
    result, group_list = example.getGroupList()

where "result" would be the return value of the getGroupList() function (the "int"), and "group_list" is the pointer-to-a-pointer converted into a Python sequence (tuple or list).

Hope that gets you going in the right direction.


Render me gone, ||| Bob ^(===)^ ---------------------------------oOO--(_)--OOo--------------------------------- I'm not so good with advice...can I interest you in a sarcastic comment?
------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d
_______________________________________________
Swig-user mailing list
Swig-user <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/swig-user
Russell Johnston | 1 Feb 19:16
Picon

SWIG struct members are freed prematurely by Java's garbage collector

I have a C++ library that is called by Java through a SWIG-based
interface. On the Java side, I build up a structure containing
pointers to arrays of other structures, using the default struct
interface andcarrays.i's %array_class.

Because Java's garbage collector is not aware of the members of the
top-level struct, the array is sometimes freed, whereon its finalizer
delete[]s its backing memory. I need a way around this, preferably
without duplicating the struct in Java, since it's rather large.

A minimal example looks like this (although it probably won't trigger
the bug since it doesn't do much):

C++/SWIG:

%module example

%include "carrays.i"
%array_class(object, objectArray);

struct object {
    unsigned int id;
    char *name;
};

struct data {
    size_t nobjects;
    object *objects;
};

void use_data(data*);

Java:

public class Example {
    private static data writeData() {
        data d = new data();
        objectArray os = new objectArray(3);
        for (int i = 0; i < 3; i++) {
            object o = new object();
            o.setId(i);
            o.setName("obj" + i);
            os.setitem(i, o);
        }
        d.setNobjects(3);
        d.setObjects(os.cast());

        return d;
    }

    public static void main(String[] args) {
        data d = writeData();
        example.use_data(d);
    }
}

------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d
_______________________________________________
Swig-user mailing list
Swig-user <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/swig-user
John Pye | 2 Feb 00:45
Favicon

Re: Any success building SWIG/Python extensions with MinGW-w64?

It looks as though the problem here is a bug in one of the Python 2.7
header files.
http://ascend4.org/Building_ASCEND_for_64-bit_Windows#Python_bindings
http://bugs.python.org/issue4709

After applying the patch attached to that bug report, my 'swigtest'
example works perfectly. It's not to say that other MinGW-w64 issues
don't remain, but so far it's looking good.

On Sat, Jan 28, 2012, at 09:35 AM, John Pye wrote:
> Hi all
> 
> I have been trying to compile my SWIG-based Python extension using
> MinGW-w64, the MinGW compiler that targets 64-bit Windows. I have a
> example that works fine on Linux but fails with a segfaul on Windows
> during Python shutdown.
> 
--

-- 
John Pye
john <at> curioussymbols.com

------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d
redapple | 2 Feb 15:27
Picon

Static Function in 64 bit Machine


I used swig to wrapped some C++ classes used in the python. On 32 bit
windows, it works very well.
Recently I build all my applications on 64 bit machine, still using swig to
wrap the same classes into the python. However, some classes caused the
python interpreter crash.

For example, I have a util.lib in C++ which includes a few c++ classes. I
have a util.i to define what classes should wrapped out. Then generated
_util.pyd used in python.

Then in python 2.7,

import _util
quit()    ----- python interpreter crash!

I checked and found _util.pyd works (no crash) if I remove a class A from
util.lib, this class A defines static function which returns a pointer.

I'm wondering what causing the crash problem and how to fix it. Any help
will be appreciated.

BTW, python is 2.7.2 64 bit version.  My application is build by MSVS 2008
amd64 compiler.

Thank you.

--

-- 
View this message in context: http://old.nabble.com/Static-Function-in-64-bit-Machine-tp33238570p33238570.html
Sent from the swig-user mailing list archive at Nabble.com.

------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d
Bob Hood | 2 Feb 15:50
Picon
Gravatar

Re: Static Function in 64 bit Machine

On 2/2/2012 7:27 AM, redapple wrote:
> For example, I have a util.lib in C++ which includes a few c++ classes. I
> have a util.i to define what classes should wrapped out. Then generated
> _util.pyd used in python.
>
> Then in python 2.7,
>
> import _util
> quit()    ----- python interpreter crash!

You may be bypassing some crucial setup/teardown functions in the Python
import module by importing the shared library directly.  Is there a reason
you're not importing "util", which is the "util.py" import module that loads
"_util"?

Render me gone,                       |||
Bob                                 ^(===)^
---------------------------------oOO--(_)--OOo---------------------------------
    I'm not so good with advice...can I interest you in a sarcastic comment?

------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d
William S Fulton | 3 Feb 07:54
Picon

Re: Lifetime of objects contained in std::vector (Python)

On 01/12/11 11:38, Andrew Ward wrote:
> Josh Cherry<jcherry<at>  ncbi.nlm.nih.gov>  writes:
>
>> Alternatively, it might work to provide or %apply an "out" typemap that
>
> Hi Josh,
>
> I have managed to get this working, here is the solution:
>
> %define RETURN_COPY_FROM_VECTOR(TYPE)
> %typemap(out) TYPE&  front {
> 	$result = SWIG_NewPointerObj(%new_copy(*$1, $*ltype), $descriptor,
>          SWIG_POINTER_OWN | %newpointer_flags);
>    }
> %typemap(out) TYPE&  back {
> 	$result = SWIG_NewPointerObj(%new_copy(*$1, $*ltype), $descriptor,
>          SWIG_POINTER_OWN | %newpointer_flags);
>    }
> %typemap(out) TYPE&  __getitem__ {
> 	$result = SWIG_NewPointerObj(%new_copy(*$1, $*ltype), $descriptor,
>          SWIG_POINTER_OWN | %newpointer_flags);
>    }
> %enddef
>
> RETURN_COPY_FROM_VECTOR(X)
>
>
> In the process I have found a bug in the Python std::vector implementation.
> The __getitem__ method has two versions, one takes an index, the other takes
> a slice object. The version that takes a slice object returns a new std::vector
> but does not use SWIG_POINTER_OWN and therefore leaks memory.
Which version of SWIG are you using because I can't see this problem. 
This overload of __getitem__:

   std::vector<_Tp,_Alloc >* __getitem__(PySliceObject *slice);

has a %feature("new") for ensuring SWIG_POINTER_OWN gets generated to 
take ownership of the memory. And indeed the generated code does have 
SWIG_POINTER_OWN in the wrappers, so there is no memory leak.

William

------------------------------------------------------------------------------
Try before you buy = See our experts in action!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-dev2
William S Fulton | 3 Feb 07:59
Picon

Re: Lifetime of objects contained in std::vector (Python)

On 03/02/12 06:54, William S Fulton wrote:
> On 01/12/11 11:38, Andrew Ward wrote:
>> Josh Cherry<jcherry<at> ncbi.nlm.nih.gov> writes:
>>
>>> Alternatively, it might work to provide or %apply an "out" typemap that
>>
>> Hi Josh,
>>
>> I have managed to get this working, here is the solution:
>>
>> %define RETURN_COPY_FROM_VECTOR(TYPE)
>> %typemap(out) TYPE& front {
>> $result = SWIG_NewPointerObj(%new_copy(*$1, $*ltype), $descriptor,
>> SWIG_POINTER_OWN | %newpointer_flags);
>> }
>> %typemap(out) TYPE& back {
>> $result = SWIG_NewPointerObj(%new_copy(*$1, $*ltype), $descriptor,
>> SWIG_POINTER_OWN | %newpointer_flags);
>> }
>> %typemap(out) TYPE& __getitem__ {
>> $result = SWIG_NewPointerObj(%new_copy(*$1, $*ltype), $descriptor,
>> SWIG_POINTER_OWN | %newpointer_flags);
>> }
>> %enddef
>>
>> RETURN_COPY_FROM_VECTOR(X)
>>
>>
>> In the process I have found a bug in the Python std::vector
>> implementation.
>> The __getitem__ method has two versions, one takes an index, the other
>> takes
>> a slice object. The version that takes a slice object returns a new
>> std::vector
>> but does not use SWIG_POINTER_OWN and therefore leaks memory.
> Which version of SWIG are you using because I can't see this problem.
> This overload of __getitem__:
>
> std::vector<_Tp,_Alloc >* __getitem__(PySliceObject *slice);
>
> has a %feature("new") for ensuring SWIG_POINTER_OWN gets generated to
> take ownership of the memory. And indeed the generated code does have
> SWIG_POINTER_OWN in the wrappers, so there is no memory leak.
Not to worry, I found the bug report and I am looking at the version 
which includes the already committed fix.

William

------------------------------------------------------------------------------
Try before you buy = See our experts in action!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-dev2
jcupitt | 3 Feb 14:39
Picon
Gravatar

OUTPUT args from C++ member functions?

Hi all,

I'm having some trouble with output args from C++ member functions in
swig 1.3.40 (the one that comes with current ubuntu).

I have a class like this in a header:

-------
class VImage ... {
    ...
    double test_member( double a, double b, double *c, double *d );

}
--------

With a body like this (ie. it returns three doubles, two via output args):

------
double VImage::test_member( double a, double b, double *c, double *d )
{
        *c = a + b;
        *d = a - b;
        return a * b;
}
--------

In my VImage.i file I have this:

-------
%include "typemaps.i"

extern double vips::VImage::test_member(double INPUT, double INPUT,
        double *OUTPUT, double *OUTPUT);

%include VImage.h
------

Looking at the generated code, it seems to have linked up the typemap
with the member, since it includes things like this:

----
res4 = SWIG_ConvertPtr(obj3, &argp4,SWIGTYPE_p_double, 0 |  0 );
  if (!SWIG_IsOK(res4)) {
----

ie. it's understood that arg4 is a result, but the Python wrapper
still insists on 4 arguments:

print a.test_member(1, 2)
TypeError: VImage_test_member() takes exactly 5 arguments (3 given)

I'm sure I'm being dumb :( Can anyone shed any light on my dumbness?

John

------------------------------------------------------------------------------
Try before you buy = See our experts in action!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-dev2
redapple | 3 Feb 15:17
Picon

Re: Static Function in 64 bit Machine


Bob, actually same thing happen if I do 

import util

I just want to separate to make it clear which module causes problem. That's
why I just type:

import _util

Thank you. Still struggling. 

Bob Hood wrote:
> 
> 
> You may be bypassing some crucial setup/teardown functions in the Python
> import module by importing the shared library directly.  Is there a reason
> you're not importing "util", which is the "util.py" import module that
> loads
> "_util"?
> 
> 
> Render me gone,                       |||
> Bob                                 ^(===)^
> ---------------------------------oOO--(_)--OOo---------------------------------
>     I'm not so good with advice...can I interest you in a sarcastic
> comment?
> 
> 
> ------------------------------------------------------------------------------
> Keep Your Developer Skills Current with LearnDevNow!
> The most comprehensive online learning library for Microsoft developers
> is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
> Metro Style Apps, more. Free future releases when you subscribe now!
> http://p.sf.net/sfu/learndevnow-d2d
> _______________________________________________
> Swig-user mailing list
> Swig-user <at> lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/swig-user
> 
> 

--

-- 
View this message in context: http://old.nabble.com/Static-Function-in-64-bit-Machine-tp33238570p33256873.html
Sent from the swig-user mailing list archive at Nabble.com.

------------------------------------------------------------------------------
Try before you buy = See our experts in action!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-dev2

Gmane