【问题标题】:Python ctypes: calling a function with custom types in cPython ctypes:在c中调用具有自定义类型的函数
【发布时间】:2018-10-04 20:06:24
【问题描述】:

我正在尝试包装 pre-existing c code 以在 Linux 中的 Python 中使用。我对 c 的经验很少,我目前正在使用 ctypes 解决这个问题。我的 C 函数需要一个带有自定义类型条目的二维数组,我不知道如何在 python 中重新创建它以将其传递给 c 函数。

这是我试图调用的函数:

void usbBuildGainTableAI_USB1808(libusb_device_handle *udev, Calibration_AIN table[NCHAN_1808][NGAINS_1808])
{

  int i, j;
  uint16_t address = 0x7000;  // base address of ADC calibration coefficients.

  for (i = 0; i < NCHAN_1808; i++) {
    for (j = 0; j < NGAINS_1808; j++) {
      usbMemAddressW_USB1808(udev, address);
      usbMemoryR_USB1808(udev, (uint8_t *) &table[i][j].slope, sizeof(float));
      address += 4;
      usbMemAddressW_USB1808(udev, address);
      usbMemoryR_USB1808(udev, (uint8_t *) &table[i][j].offset, sizeof(float));
      address += 4;
    }
  }
  return;
}

头文件已经定义

typedef struct Calibration_AIN_t {
  float slope;
  float offset;
} Calibration_AIN;

其中 NCHAN_18081 和 NGAINS_1808 是常量,而 udev 是整数。我关注了一个关于多维数组的older question,并尝试制作一个类似于 c 代码中的结构。

_1808 = CDLL(os.path.abspath("lib1808.so"))

NCHAN_1808 = 8  # max number of A/D channels in the device
NGAINS_1808 = 4  # max number of gain levels

class Calibration_AIN(Structure):
    _fields_ = [("slope", c_float), ("offset", c_float)]

class AINarray(Structure):
    _fields_ = [("array", (Calibration_AIN() * NCHAN_1808) * NGAINS_1808)]

table_AIN = AINarray()

_1808.usbBuildGainTableAI_USB1808(udev, table_AIN)

但是这样做有几个问题:自定义类型 Calibration_AIN 不能像 int 或 float 那样使用运算符 * 填充到数组中,而且我不能将自定义类型传递给 c。我也尝试过在 Python 中使用列表列表制作数组,但我无法将其转换为可通过 ctypes 传递给 c 的任何有用的东西。

如何在不修改c代码的情况下从python调用这个函数?任何帮助将不胜感激,如果我应该只学习 c 并尝试用 c 或 Cython 编写程序,请告诉我。 Ctypes 可能不是最好的方法。

【问题讨论】:

    标签: python c arrays python-2.7 ctypes


    【解决方案1】:

    行:

    _fields_ = [("array", (Calibration_AIN() * NCHAN_1808) * NGAINS_1808)]
    

    应该引发 TypeError,因为您实例化 Calibration_AIN。我相信你的意思是:

    _fields_ = [("array", (Calibration_AIN * NCHAN_1808) * NGAINS_1808)]
    

    但即便如此,您也不需要 AINarray 包装器。根据[Python]: Arrays,您可以执行以下操作:

    Calibration_AIN_Table = (Calibration_AIN * NCHAN_1808) * NGAINS_1808
    

    然后,为了初始化一个实例,请执行以下操作:

    >>> cat = Calibration_AIN_Table()
    >>> for i in range(NGAINS_1808):
    ...     for j in range(NCHAN_1808):
    ...         cat[i][j].slope = i * j
    ...         cat[i][j].offset = i * i * j
    ...
    >>> cat[2][3].slope
    6.0
    

    【讨论】:

    • 感谢您的回复。当我这样做时,cat[i][j].slope = i * jTypeError: _cytpes.PyCArrayType object does not support indexing 行出现错误
    • cat = Calibration_AIN_Table(), cat 应该是一个实例注意()Calibration_AIN_Table之后。
    猜你喜欢
    • 1970-01-01
    • 2017-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-14
    • 1970-01-01
    相关资源
    最近更新 更多