【问题标题】:python ctypes pointer arithmeticpython ctypes指针算法
【发布时间】:2017-11-24 21:18:36
【问题描述】:

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 进行指针运算吗?我知道您可以通过它的索引访问数组的值,但我不希望这样,因为我不想在我的结构中引用长度

【问题讨论】:

  • 为什么?你这样做有什么收获?
  • 这不是为什么,而是如何。这是一个简单的例子来展示我想要什么,而不是我做什么。
  • 我不同意...这对我来说似乎是XY Problem
  • 这和C语言有什么关系?你如何在 C 中做某事与如何在 Python 中做完全无关。我同意@TemporalWolf:这是一个 XY 问题。
  • 指针算法没有实现,但是你可以索引一个指针。这里的问题是,它调用了 getfunc,对于像c_short 这样的简单类型,它会自动将索引值转换为 Python 整数。对于简单类型的子类,此行为被禁用,因为假定您需要保留派生类型。因此,如果使用c_short 的子类,那么您可以使用ctypes.pointer(foo.Bar[2])。还有其他选择,但越来越麻烦。

标签: python ctypes


【解决方案1】:

它很复杂,但是这会在 tab 中的一个字节偏移处计算一个 c_short 对象,该对象共享其缓冲区,然后获取指向它的指针:

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

【讨论】:

  • 我认为,如果不能使用c_short 的子类,我认为下一步是使用指向单位长度数组的指针,例如foo.end_Bar = POINTER(tab._type_ * 1)(tab)[2]。如果tab 不再可用,您可以使用foo.end_Bar = POINTER(foo.Bar._type_ * 1)(foo.Bar.contents)[2]
猜你喜欢
  • 1970-01-01
  • 2014-01-23
  • 1970-01-01
  • 2017-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-24
  • 1970-01-01
相关资源
最近更新 更多