Manipulating pointers in C using ctypes

Jason Scheirer jason.scheirer at gmail.com
Fri Jan 8 20:02:50 CET 2010


On Jan 8, 7:37 am, Daniel Platz <mail.to.daniel.pl... at googlemail.com>
wrote:
> 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.
>
> With kind regards,
>
> Daniel

try this:

__declspec(dllexport) void* create()
{
        double* ptr = new double;
        *ptr = 2.2;
        printf("Pointer address \t %p \n", ptr);
        printf("Value at pointer \t %f \n", ptr[0]);
        return (void*) ptr;
}

Basically once you leave create() the address being used for number is
no longer valid. The other implication for this is you are going to
need a delete() function to free that memory you allocated for the
double as well.



More information about the Python-list mailing list