how to know argument name with which a function of extended c called

Aaron Brady castironpi at gmail.com
Wed Apr 15 05:27:07 EDT 2009


On Apr 15, 3:52 am, John Machin <sjmac... at lexicon.net> wrote:
> On Apr 15, 6:13 pm, rahul <rahul03... at gmail.com> wrote:
>
>
>
> > On Apr 14, 6:24 pm, John Machin <sjmac... at lexicon.net> wrote:
>
> > > On Apr 14, 10:35 pm, rahul <rahul03... at gmail.com> wrote:
>
> > > > Hi,
> > > >   i need to write a 'c extension function' in this function i need to
> > > > change argument value with  which this function called.
>
> > > The appropriate way for a function to give output is to return a
> > > value, or a tuple of values.
>
> > > example:
>
> > > def get_next_token(input_buffer, offset):
> > >    """get next lexical token, starting at offset
> > >       return (the_token, new offset)"""
> > >    length = find_len_of_token_somehow(input_buffer, offset)
> > >    new_offset = offset + length
> > >    return input_buffer[offset:new_offset], new_offset
>
> > > and you can call it by
> > >    token, pos = get_next_token(buff, pos)
> > >    return input
>
> > > >   ie,
> > > >          if a python code like
> > > >             import changeValue as c
> > > >             arg="old value"
> > > >             c.changeValue(arg)
> > > >             print arg
>
> > > Fortunately, you can't construct such a thing in Python or in a C
> > > extension. Consider the following:
>
> > > print "two", 2
> > > c.changeValue(2)
> > > print "two maybe", 2
>
> > > What would you want to it to print the second time?
> > > two maybe new value?
>
> > > >  then it print "new value"
>
> > > >  i write code like this..
>
> > > > static PyObject *changeValue(PyObject *self,PyObject *args){
> > > >         PyObject *sampleObj, *m ;
> > > >         char *argName;
>
> > > >       if (!PyArg_ParseTuple(args, "O", &sampleObj)){
> > > >                 return NULL;
> > > >       }
>
> > > >    m = PyImport_AddModule("__main__");
>
> > > This means you are assuming/hoping this function will be called only
> > > from the main script ...
>
> > > >    PyObject_SetAttrString(m, argName, "new value");
>
> > > Even if you know the name, you have the problem that it is changing
> > > the __main__ module's globals ... but the arg could be local or it
> > > could be an expression ...
>
> > > >    return Py_BuildValue("");
>
> > > > }
>
> > > > But for this i need to know the argument name with which this function
> > > > called .
> > > > Is this possible to know argument name in extended c function? if yes,
> > > > than how i can do it???
>
> > > No, it's not possible to know the argument name (without help from the
> > > caller e.g. keyword args), it may not even have a name, it may have
> > > multiple names ... this is just another variation of the old "what is
> > > the name of my object" FAQ.
>
> > > Why don't you tell us what you are trying to achieve (a higher-level
> > > goal than "I need to poke some value at/into some variable of doubtful
> > > name and unknowable location"), and then we might be able to give you
> > > some ideas.
>
> > > HTH,
> > > John
>
> > Hi John,
> >    thanks for your great full information,
> >      But, In my project anyhow i have to change argument value in some
> > cases.
>
> I say again: You can't do that. If you care to explain AT A HIGHER
> LEVEL than "change argument value" what you are trying to achieve,
> then some help might be available.
>
> If you are translating from C to Python and you have a function that
> is expected to be called like func(in1, &out2, &inout3) then you will
> have to write the function as
>    def func(in1, inout3):
>       # calculate out2
>       # calculate new_inout3
>       return out2, new_inout3
> (or the equivalent in a C-extension) and the caller will need to be
> changed to do
>    out2, inout3 = func(in1, inout3)
>
> Alternatively, leave the function in C and provide a wrapper function
> in C that bridges the different argument-passing conventions. There
> are various options for doing this -- the Cython/boost/ctypes/etc
> gurus can help with this once you've explained what your real
> requirement is.
>
> > can we pass pointer  of an variable in extended c function.
>
> Python doesn't have "variables". It has objects, which have zero, one,
> or many names. The names exist in namespaces of various types: local
> to a function/method, attribute of a class, attribute of a class
> instance, global to a module, ... there is no unified "address"
> concept; the concept "&arg" has no meaning and no means of realising
> it as a vehicle for doing the equivalent of C's "*pointer =
> new_value".
>
> HTH,
> John

There is a limited subset of cases where a function can modify its
argument.  The first of course is with mutable types, but the function
would not operate successfully on future types.  If it only needs to
handle one mutable type, then it's straightforward.

The second is with the 'ctypes.byref' function, which only accepts
ctypes types and structures, but can perform the swap, again, if the
types are known.

The generic solution is to just retrieve your value from the same
place in a container every time, i.e. 'Globals.val1', which you can
read and write at will.  The container and attribute can be determined
at run-time (untested):

def swap( namespace, name1, name2 ):
  temp= getattr( namespace, name1 )
  setattr( namespace, name1, getattr( namespace, name2 ) )
  setattr( namespace, name2, temp )



More information about the Python-list mailing list