Manipulating pointers in C using ctypes
Mark Tolonen
metolone+gmane at gmail.com
Sat Jan 9 00:09:05 EST 2010
More information about the Python-list mailing list
Sat Jan 9 00:09:05 EST 2010
- Previous message (by thread): Manipulating pointers in C using ctypes
- Next message (by thread): Manipulating pointers in C using ctypes
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
"Daniel Platz" <mail.to.daniel.platz at googlemail.com> wrote in message news:08bda34e-9bee-44b1-b2de-80d647151786 at a15g2000yqm.googlegroups.com... > Hello! > > I have to ask a newbie question about manipulating pointers in C using > ctypes. I have a C dll with two functions. The first one creates a > pointer and returns it to python. The second one takes a pointer as an > argument shows its address and the value at which it is pointing. This > I have implemented using the following code > > ----------- -------- pointers.c ---------------------------- > #include <stdio.h> > #ifdef __cplusplus > extern "C" { // only need to export C interface if > // used by C++ source code > using namespace std; > #endif > > __declspec(dllexport) void* create() > { > double number = 2.2; > double* ptr = &number; > printf("Pointer address \t %p \n", ptr); > printf("Value at pointer \t %f \n", ptr[0]); > return (void*) ptr; > } > > __declspec(dllexport) int show(double* ptr) > { > printf("Pointer address \t %p \n", ptr); > printf("Pointer value \t %f\n", *ptr); > *ptr = 2.4; > printf("New pointer value \t %f\n", *ptr); > return 0; > } > > #ifdef __cplusplus > } > #endif > ------------------------------------------------------------------------ > > Please note that in the second function, the show function, I want to > manipulate the value at which the pointer points. > Now, I call this function from python with the following script. > > --------------------------- pointers.py -------------------------- > import ctypes as ct > > # Load dll > pointers = ct.cdll.LoadLibrary('pointers.dll') > getattr(pointers, 'create') > getattr(pointers, 'show') > pointers.create.restype = ct.c_void_p > > # Create pointer in C > ptr = pointers.create() > > # Show pointer address and value > print 'Adress returned to python ' +hex(ptr) > pointers.show(ct.c_void_p(ptr)) > ------------------------------------------------------------------- > > Calling this script gives me the following output: > > Pointer address 0021E508 > Value at pointer 2.200000 > Adress returned to python 0x21e508 > Pointer address 0021E508 > Pointer value 0.000000 (2.20000 expected) > New pointer value 2.400000 (2.40000 expected) > > But the script returns also an error. > > WindowsError: exception: access violation reading 0x40033333 > WARNING: Failure executing file: <pointers.py> > > Another thing that I find strange is that the return value of > pointers.create is actually an integer instead of an ct.c_void_p > object. > > Moreover, I also tried to directly manipulate the address of the > pointer given as an argument to pointers.show. But when it returns to > python the pointer points still at the same address as before the > function call. > > Can someone help me with this problem? I would be very glad about an > answer. As Jason observed, your create() function creates a number on the local stack, which becomes invalid once the function returns. If you don't want to worry about freeing the object created in Jason's solution, you can create the double in python yourself and let create initialize it: -------------- pointers.py ---------------------- import ctypes as ct pointers = ct.CDLL('pointers.dll') pointers.create.restype = None pointers.show.restype = None dbl = ct.c_double() print ct.byref(dbl),dbl ptr = pointers.create(ct.byref(dbl)) # Show pointer address and value print 'Value returned to python: %f' % dbl.value pointers.show(ct.byref(dbl)) print 'Value returned to python: %f' % dbl.value -------------- pointers.c ------------------------ #include <stdio.h> __declspec(dllexport) void create(double* ptr) { *ptr = 2.2; printf("Pointer address %p\n", ptr); printf("Value at pointer %f\n", *ptr); } __declspec(dllexport) void show(double* ptr) { printf("Pointer address %p\n", ptr); printf("Pointer value %f\n", *ptr); *ptr = 2.4; printf("New pointer value %f\n", *ptr); } -------------- OUTPUT ------------------------- <cparam 'P' (00A05DC8)> c_double(0.0) Pointer address 00A05DC8 Value at pointer 2.200000 Value returned to python: 2.200000 Pointer address 00A05DC8 Pointer value 2.200000 New pointer value 2.400000 Value returned to python: 2.400000 ----------------------------------------------------- HTH, Mark
- Previous message (by thread): Manipulating pointers in C using ctypes
- Next message (by thread): Manipulating pointers in C using ctypes
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Python-list mailing list