views:

257

answers:

4

I am using a C++ SDK where there is a function like (it has a python wrapper, but not docs):

getPos ( int uvId, float & u, float & v ) const

How do I specify in Python so that the passed variables are changed?

I tried this example to see if I could modify floats inside a function, but it didn't work, so printed 12.0:

def change ( a ) :

    a = 35.0


b = 12.0

change ( b )

print b

So how do I call this function that I can change 2 external floats in Python?

Related:

A: 

For simple cases have the function return the new value.

For more complicated cases you can pass in a object or a list and have that changed:

def foobar(alist):
    alist[0] = 10

blist = [42]
foobar(blist)
print blist[0]

Edit:

For wrapping C++ references there isn't any standard way (basic python interfaces are at the C level - not C++) - so it depends how the python interface has been implemented - it might be arrays, or returning multiple values. I'm not sure how boost.python handles it but you might start there, or maybe look under a debugger to see how the parameter are handled.

Douglas Leeder
Thanks but the getPos function and many more is C++ and I can't change them. Everything is wrapped in Python so I assume there must be a way to use it.
Joan Venge
+5  A: 

In Python:

def getPos(uvID):
    # compute u, v
    return u, v

# 
u, v = getPos(uvID)
J.F. Sebastian
+1: multiple return values -- that's usually the essential meaning behind the C/C++ code.
S.Lott
Thanks guys, but in the getUV function case above, they didn't do it like that, wish they did but no.
Joan Venge
In which case, you have to write your own API to make that piece of C++ amenable to Python.
S.Lott
Thanks I wish I could but it's 3rd party software. I can't believe they overlooked this.
Joan Venge
+2  A: 

As far I know, Python doesn't support call-by-reference, so the exact code you are suggesting doesn't work (obviously).

The tool (or person) that generated the Python wrapper for the C++ function must have done something special to support this function (hopefully, or you won't be able to use it). Do you know what tool was used to generate the wrapper?

Usually tools like this will generate some sort of container data type:

b.value = 12.0
change(b)
print b.value
Tom Lokhorst
Thanks, they used Swig, but I don't know how they could do it without changing the return type.
Joan Venge
To be fair, everything is (kinda) call-by-reference, just that numbers are immutable. So you are not changing attributes of the object bound to the name a in the function, but rebinding a to a completely different object.
Mike Boers
Thanks Mike, this is what I was thinking.
Joan Venge
I'm not an expert in Python, but I think everything is passed by value (by copying). It's just that since everything is an object, the thing that gets copied is always a reference (yeah, that sounds confusing).
Tom Lokhorst
So, you always have copies of a reference to some object. However, some objects (like lists) you can change, while others (like numbers or tuples) can't be changed, they're immutable.
Tom Lokhorst
+2  A: 

You're going to have to resort to ctypes.

Specifically, see http://www.python.org/doc/2.5.2/lib/ctypes-passing-pointers.html

S.Lott