From: Bob H. <bh...@co...> - 2012-03-19 18:40:33
|
On 3/19/2012 11:49 AM, Russell E. Owen wrote: > The swig 2.0 manual section "10.6.1 Typemaps for arrays" has a nice > example for getting arrays in structs to work. > <http://www.swig.org/Doc2.0/Typemaps.html#Typemaps_nn40> > Unfortunately I can't get it to work. I hope it's just a simple user > error. > > I made a minimal test case that attempts to wrap this simple struct > using the in, out and memberin typemaps in the typemap example mentioned > above. > > *** swigtest.h *** > #pragma once > > struct TestBlk { > float f[3]; > }; > > > The code is appended, and a complete copy, including a scons builder > file and python test file, is available here: > <http://www.astro.washington.edu/users/rowen/testswig_cfloat.zip> > > What I find is that the "out" typemap works perfectly (I can retrieve f > from TestBlk) but the "in" and "memberin" typemaps are ignored -- the > swig wrapper acts identically whether those are present or absent, and > it's not pretty: If I attempt to set elements of TestBlk.f individually > (e.g. test.f[0] = 4.0) the command is accepted but ignored. If I attempt > to set f to a list of 3 floats, the command is rejected. > > Any ideas? I recall running into this same sort of issue while wrapping Python for a major 3D animation package. I posted to the list about it, and was mildly surprised to discover that SWIG does not perform individual element accesses, but rather migrates whole arrays at once (you might be able to find it if you search back through the archives). What this comes down to is the fact that "out" is going to behave as you expect with individual element access because /the entire array is transferred to the target language environment with each access/. This means that when you access your array using: f0 = test.f[0] Then the entire array (f[3]) will be copied to Python's stack, and then the single element [0] will be pulled from it and assigned to your variable ('f0'). So, the following code: f0 = test.f[0] f1 = test.f[1] f2 = test.f[2] would actually end up copying your entire array three times! Knowing that, then it becomes clearer that the "out" version won't set an individual element into the array and pass it back to C++. Instead, it will copy the entire array locally, set the value into the specific element...and then just discard the array. To improve efficiency, I had to resort (in the Python examples I constructed) to setting up cases where exposed structure array members are pulled down to the Python environment locally in their entirety until the user is done working with them, and then providing a means for passing the modified array back to C++ in a single, whole step. AFAIK, this is still the case with SWIG (2.0.4). Render me gone, ||| Bob ^(===)^ ---------------------------------oOO--(_)--OOo--------------------------------- I'm not so good with advice...can I interest you in a sarcastic comment? |