ctypes - python2.7.3 vs python3.2.3

Discussion in 'Python' started by Rolf, Aug 28, 2012.

  1. Rolf

    Rolf Guest

    ctypes works as I would expect with python2.7.3.

    However, when I upgrade to python3.2.3 things don't seem to work right. Look below for details.

    I am not sure where I am going wrong.

    Shared Library
    ==============
    #include <stdint.h>
    #include <string.h>

    extern "C"
    {
    int main();
    uint32_t myfunction (char **);
    }

    uint32_t myfunction (char ** _mydata)
    {
    char mydata[16];

    strcpy(mydata, "Hello Dude!");

    *_mydata = mydata;

    return 0;
    }

    int main()
    {
    return 0;
    }

    Python 2.7.3 which works as I would expect
    ==========================================
    > python2.7 -V

    Python 2.7.3

    > cat py27.py

    #!/usr/bin/env python2.7

    from __future__ import print_function
    from __future__ import unicode_literals

    from ctypes import *

    lib = CDLL('libtest.so')
    o_result = c_char_p()
    lib.myfunction(pointer(o_result))
    print(repr(o_result.value))

    > ./py27.py

    'Hello Dude!'

    Python 3.2.3 return string gets mangled
    =======================================
    > python3 -V

    Python 3.2.3

    > cat py3.py

    #!/usr/bin/env python3

    from ctypes import *

    lib = CDLL('libtest.so')
    o_result = c_char_p()
    lib.myfunction(pointer(o_result))
    print(repr(o_result.value))

    > ./py3.py

    b'\xd8\xb0y\to Dude!'

    Every time I run it, I get a different set of values.
     
    Rolf, Aug 28, 2012
    #1
    1. Advertising

  2. Rolf

    John Gordon Guest

    In <> Rolf <> writes:

    > uint32_t myfunction (char ** _mydata)
    > {
    > char mydata[16];


    > strcpy(mydata, "Hello Dude!");


    > *_mydata = mydata;


    > return 0;
    > }


    mydata is an auto variable, which goes out of scope when myfunction()
    exits. *_mydata ends up pointing to garbage.

    --
    John Gordon A is for Amy, who fell down the stairs
    B is for Basil, assaulted by bears
    -- Edward Gorey, "The Gashlycrumb Tinies"
     
    John Gordon, Aug 28, 2012
    #2
    1. Advertising

  3. Rolf

    MRAB Guest

    On 28/08/2012 22:35, Rolf wrote:
    > ctypes works as I would expect with python2.7.3.
    >
    > However, when I upgrade to python3.2.3 things don't seem to work right. Look below for details.
    >
    > I am not sure where I am going wrong.
    >
    > Shared Library
    > ==============
    > #include <stdint.h>
    > #include <string.h>
    >
    > extern "C"
    > {
    > int main();
    > uint32_t myfunction (char **);
    > }
    >
    > uint32_t myfunction (char ** _mydata)
    > {
    > char mydata[16];
    >
    > strcpy(mydata, "Hello Dude!");
    >
    > *_mydata = mydata;
    >
    > return 0;
    > }
    >
    > int main()
    > {
    > return 0;
    > }
    >

    [snip]
    What you're doing in 'myfunction' looks wrong to start with. It's
    returning the address of the local array 'mydata' which allocated on
    the stack when the function is entered. When the function is left it's
    deallocated, so the address becomes a dangling pointer. That it gave a
    reasonable result with Python 2.7.3 is down to pure luck.
     
    MRAB, Aug 28, 2012
    #3
  4. Rolf

    Jan Kuiken Guest

    On 8/28/12 23:51 , John Gordon wrote:
    > In <> Rolf <> writes:
    >
    >> uint32_t myfunction (char ** _mydata)
    >> {
    >> char mydata[16];

    >
    >> strcpy(mydata, "Hello Dude!");

    >
    >> *_mydata = mydata;

    >
    >> return 0;
    >> }

    >
    > mydata is an auto variable, which goes out of scope when myfunction()
    > exits. *_mydata ends up pointing to garbage.
    >


    I'm not completely sure, but i think this can be solved by using:

    static char mydata[16];

    (Btw.: I don't know why you use char ** _mydata, i would use
    char * _mydata, but then again, i'm not very familiar with
    ctypes)

    Jan Kuiken
     
    Jan Kuiken, Aug 29, 2012
    #4
  5. Rolf

    John Gordon Guest

    In <9a74$503e88dd$546bb230$> Jan Kuiken <> writes:

    > >> uint32_t myfunction (char ** _mydata)
    > >> {
    > >> char mydata[16];

    > >
    > >> strcpy(mydata, "Hello Dude!");

    > >
    > >> *_mydata = mydata;

    > >
    > >> return 0;
    > >> }

    > >
    > > mydata is an auto variable, which goes out of scope when myfunction()
    > > exits. *_mydata ends up pointing to garbage.


    > I'm not completely sure, but i think this can be solved by using:


    > static char mydata[16];


    That will solve the immediate problem, however it makes myfunction()
    non-reentrant.

    > (Btw.: I don't know why you use char ** _mydata, i would use
    > char * _mydata, but then again, i'm not very familiar with
    > ctypes)


    He uses char **_mydata because he wants myfunction()'s caller to see the
    new value of _mydata, which it wouldn't if it were just char *_mydata.

    --
    John Gordon A is for Amy, who fell down the stairs
    B is for Basil, assaulted by bears
    -- Edward Gorey, "The Gashlycrumb Tinies"
     
    John Gordon, Sep 7, 2012
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Xavier
    Replies:
    0
    Views:
    427
    Xavier
    Aug 6, 2003
  2. Skip Montanaro
    Replies:
    1
    Views:
    441
    Thomas Heller
    Aug 7, 2003
  3. snacktime
    Replies:
    13
    Views:
    570
    Dan Sommers
    Feb 22, 2005
  4. Uwe Mayer

    changing from python2.3 to python2.4

    Uwe Mayer, Apr 8, 2005, in forum: Python
    Replies:
    1
    Views:
    307
    =?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=
    Apr 9, 2005
  5. Ksenia Marasanova
    Replies:
    2
    Views:
    363
    Mike Meyer
    Nov 17, 2005
Loading...

Share This Page