Manipulating pointers in C using ctypes
Jason Scheirer
jason.scheirer at gmail.com
Fri Jan 8 14:02:50 EST 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