12

Short version: How can I get the address that a ctypes pointer points to?

Long version: I have registered a python function as a callback with a C library. The C library expects function signature of void (*p_func)(char stat, char * buf, short buf_len) so I register an appropriate python function. When I get into the python function, I want to know the memory address pointed to by buf. How can I do this?

Iain Rist
  • 976
  • 2
  • 9
  • 18

2 Answers2

18

I have fixed this myself by reading the documentation.

I wanted to know the memory location of a block of memory allocated by a library. I had the ctypes pointer that pointed to said block. To get the memory address of the block I used ctypes.addressof(p_block.contents).

The confusion arose around my understanding that p_block.contents != p_block.contents, but then I realised all p_block.contents objects have the same underlying buffer. The address of the underlying buffer is obtained with ctypes.addressof.

Iain Rist
  • 976
  • 2
  • 9
  • 18
  • 2
    That's a bit like `&(*p)` in C where `p` is a pointer. What is strange is that ctypes does not define a `value` attribute for arbitrary pointer type as returned by `ctypes.POINTER` function. The `ctypes.c_void_p` class *does* have the `value` attribute, but the class returned by `ctypes.POINTER` does not. Very odd, counterintuitive, and almost reeks of incomplete implementation. – Armen Michaeli Oct 22 '15 at 17:43
  • 2
    FYI https://bugs.python.org/issue26565, "Add value attribute to non basic pointers": >> I know one can do addressof(p.contents), but it's a bit inconsistent that c_void_p and c_char_p contain the same information in the value attribute. > The `value` of a c_char_p or c_wchar_p pointer is a Python bytes or str object. Since `value` won't consistently be the address value, it may be better to introduce a read-only `as_void` attribute that can be implemented consistently for all pointer types (including function pointers). – memeplex May 24 '16 at 21:46
  • Gotcha! Hair pulling is over. Matsalams! – daparic Jun 26 '20 at 18:09
6
real_adr = cast(anyctypespointer, c_void_p).value

Works for any kind of ctypes pointer - even function pointers etc. which lack .content

kxr
  • 4,841
  • 1
  • 49
  • 32