2017-06-21 164 views
0

ctypes可以用指针算术吗?python ctypes指针算术

首先,让我告诉你我想用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; 
} 

现在你明白我在做什么是创建整数数组,并在参考两个指针保持在结构。一个指针在开始,一个在末尾,而不是保持第一个指针和数组的长度。

现在在Python我有继承ctypes.Structure并且作为两个件,它们是ctypes.POINTER(ctypes.c_short)类型的对象。

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 

所以现在的问题。是否可能用ctypes做指针运算?我知道你可以通过索引访问数组的值,但我不想那样,因为我不想在我的结构中引用长度。

+0

为什么?通过这样做你会获得什么? – TemporalWolf

+0

这不是关于为什么,而是如何。这是一个简单的例子来展示我想要的,而不是我所做的。 – Olivier

+0

我不同意......这似乎是[XY问题](https://meta.stackexchange.com/a/66378/344593)给我的。 – TemporalWolf

回答

3

这是令人费解,但这种计算一个c_short对象以字节tab共享其缓冲区偏移,然后得到它的指针:

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 
+0

我认为下一步对我来说,如果使用'c_short'的子类不是一个选项,那么可以使用指向单位长度数组的指针,例如, 'foo.end_Bar = POINTER(tab._type_ * 1)(tab)[2]'。如果'tab'不再可用,你可以使用'foo.end_Bar = POINTER(foo.Bar._type_ * 1)(foo.Bar.contents)[2]'。 – eryksun