This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: ctypes: Pointer-to-pointer unchanged in callback
Type: Stage:
Components: Library (Lib) Versions: Python 2.5
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: theller Nosy List: albertstrasheim, theller
Priority: normal Keywords:

Created on 2006-10-10 15:16 by albertstrasheim, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (2)
msg30204 - (view) Author: Albert Strasheim (albertstrasheim) Date: 2006-10-10 15:16
This problem is from another post I made to
ctypes-users that didn't show up in the ctypes-users
archive.

C function:

extern CALLBACK_API void foo(void(*callback)(void**)) {
    void* p = 123;
    printf("foo calling callback\n");
    callback(&p);
    printf("callback returned in foo\n");
    printf("p = 0x%p\n", p);
}

I figured that while I try to find out why returning
c_void_p from a callback gives an error, I might as
well return the address via a pointer to a pointer.

In the Python code I have:

import sys
print sys.version
from ctypes import *
x_t = c_int*10
x = x_t()
def callback(ptr):
    print x
    print ptr
    ptr.contents = cast(addressof(x), c_void_p)
    print ptr.contents
#lib = cdll['libcallback.so']
lib = cdll['callback.dll']
lib.foo.argtypes = [CFUNCTYPE(None, POINTER(c_void_p))]
lib.foo(lib.foo.argtypes[0](callback))

Output when I running this script under Python 2.4.3
with ctypes 1.0.0 (I get identical results with Python
2.5 and ctypes 1.0.1):

2.4.3 (#69, Mar 29 2006, 17:35:34) [MSC v.1310 32 bit
(Intel)]
foo calling callback
<__main__.c_long_Array_10 object at 0x00963E90>
<ctypes.LP_c_void_p object at 0x00963EE0>
c_void_p(10048496)
callback returned in foo
p = 0x0000007B

For some reason, the value I assigned to ptr.contents
isn't present when we return to the C code.
msg30205 - (view) Author: Thomas Heller (theller) * (Python committer) Date: 2007-01-26 11:02
Sorry for the late reply.

This is not a bug.  To dereference a pointer in ctypes you should index with 0:
  print ptr[0]
  ptr[0] = <somethingelse>
When you replace 'ptr.contents' with 'ptr[0]' in your code then it works as expected.
In C, these two idioms are identical:

   ptr[0]
   *ptr


The sematics of ptr.contents is different although somewhat difficult to explain.
Changing ptr.contents does not change the value that the pointer points to, instead
it changes the location that the pointer points to.
History
Date User Action Args
2022-04-11 14:56:20adminsetgithub: 44110
2006-10-10 15:16:14albertstrasheimcreate