Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python ctypes pointer arithmetic

Tags:

python

ctypes

Is it possible with ctypes to make pointer arithmetic?

First, let me show you what I'm trying to do in C

#include <stdio.h>

struct Foo {
 short *Bar;
 short *end_Bar;
};

int main() {
  short tab[3] = {1,2,3};
  struct Foo foo;
  foo.Bar = tab;
  foo.end_Bar = foo.Bar + 2; // Pointer arithmetic
  short *temp = foo.Bar;
  while(temp != foo.end_Bar)
    printf("%hi", *(temp++));
  printf("%hi", *(foo.end_Bar));
  return 0;
}

Now you understand that what I'm doing is creating an array of integer, and keeping in reference two pointers in a structure. One pointer at the begining and one at the end, instead of keeping the first pointer and the length of the array.

Now in Python I have an object that inherit from ctypes.Structure and as two members which are ctypes.POINTER(ctypes.c_short) type.

import ctypes

class c_Foo(ctypes.Structure):
    _fields_ = [
       ("Bar", ctypes.POINTER(ctypes.c_short)),
       ("end_Bar", ctypes.POINTER(ctypes.c_short))
    ]

if __name__ == "__main__":
    tab = [1,2,3]
    foo = c_Foo()
    foo.Bar = (c_short * len(tab))(*tab)
    foo.end_Bar = foo.Bar + 2 # TypeError, unsupported operand

So now the question. Is it possible to do pointer arithmetic with ctypes? I know that you can access value of the array by it index, but I don't want that, because I don't want a length reference in my structure.

like image 547
Olivier Avatar asked Mar 09 '23 19:03

Olivier


1 Answers

It's convoluted, but this computes a c_short object at a byte offset in tab that shares its buffer, then gets a pointer to it:

from ctypes import *

class c_Foo(Structure):
    _fields_ = [
       ("Bar", POINTER(c_short)),
       ("end_Bar", POINTER(c_short))
    ]

tab = (c_short*3)(1,2,3)
foo = c_Foo()
foo.Bar = tab
foo.end_Bar = pointer(c_short.from_buffer(tab,sizeof(c_short)*2))
print(tab[2])
print(foo.Bar[2])
print(foo.end_Bar[0])
tab[2] = 4
print(tab[2])
print(foo.Bar[2])
print(foo.end_Bar[0])
3
3
3
4
4
4
like image 108
Mark Tolonen Avatar answered Mar 20 '23 03:03

Mark Tolonen