From: marvin p. <pub...@gm...> - 2014-05-21 15:53:11
|
OK. So, never mind. I glanced at the directorargout typemap documentation for python and didn't see anything. I've used directors with java and c# and there is nothing like that. On May 21, 2014 11:32 AM, "Bob Hood" <bh...@co...> wrote: > On 5/21/2014 8:46 AM, Marvin Greenberg wrote: > > Bob Hood wrote: > > Bump. > > On 5/8/2014 2:02 PM, Bob Hood wrote: > > I'm using SWIG 2.0.4 with Python. > > I've run into the first instance where I need to have an 'argout' > mechanism > for a Director-controlled method. Something along these lines: > > typedef double Vector[3]; > ... > class MyClass > { > ... > virtual int get_pos(Vector v); //<-- 'v' is an > output-onlyargument > }; > > with > > %feature("director") MyClass; > > in the interface file. > > I've applied the "%typemap(directorargout) Vector" and achieved the > desired > effect. However, it appears that the generated Python method continues to > require the Vector 'v' argument to the method, even though it serves no > useful > purposeand is not of a known type to Python; e.g. this works properly: > > def get_pos(self, v): > return (1, (0, 0, 0)) > > However, if I attempt to leave off the 'v' argument: > > def get_pos(self): > return (1, (0, 0, 0)) > > I get an error about the method requiring 1 argument with 2 provided. Is > there a way that I can tell SWIG that the Python-based argument is > irrelevant > (perhaps using some kind of %ignore directive) and that it should not > attempt > to pass it to the Python code when invoking PyObject_CallMethod()? > > > > I think you're misunderstanding something pretty basic about output > arguments. If you have a function or method like > > void foo(int& outarg); > > Then the implementation is going to pass the argument value by doing > something to the passed argument, not by returning extra values. Like, > > outarg = 1; > > In your method you declare the C++ method as returning an integer, but > then in your director implementation you proceed to pass out a tuple with > an int and another tuple, not an int. It "works" because python is not > statically typed. It certainly isn't doing what you think. Your get_pos > implementation would need to look something like > > def get_pos(self,v): > v[0]=0 > v[1]=1 > v[2]=2 > return 0 > > I'm not that familiar with the details of the code generated for python > directors, or how directorargout modifies it (makes it a 1 element array?) > but its really besides the point. > > > Thanks for the response, Marvin. > > There is a typemap defined (not included) that converts the (0, 0, 0) > tuple back into a double[3] for return to the caller. > > I don't believe I've misunderstood anything about output arguments (at > least, in each individual language). The issue here is the middleware code > that SWIG generates. The argument type of 'v' is opaque when it arrives in > Python ("<type 'SwigPyObject'>") *due to* the "%typemap(directorargout) > Vector" declaration, so your Python code above will not function because > 'v' is not a known Python type -- an exception will be raised. > > From the SWIG 2.x docs regarding "directorargout": > > "directorargout typemaps allow your [target language] code to emulate > this by specifying additional return values to be put into the output > parameters. ... In this case, *your return to the caller must be a list > containing the normal function return first, followed by any argout values > in order*. These argout values will be taken from the list and assigned > to the values to be returned to C++ through directorargout typemaps. In the > event that you don't specify all of the necessary values, integral values > will read zero, and struct or object returns have undefined results." > > Unless I'm misunderstanding the above passage (which is taken from the > "Ocaml" section, but I assume is valid for all target languages), the > output argument value(s) have to be part of the return statement (as in my > Python code), not assigned directly to the arguments provided to the Python > function/method (which will fail due their opaque data types). Assuming > that's correct, the argument provided (in this case 'v') is completely > useless because it is strictly designated as "output", and actually cannot > be used as input anyway because it is not an accessible data type. > > I suppose it's possible I'm missing a crucial point here. > > |