Python ctypes:在c中调用自定义类型的函数

时间:2018-04-24 14:05:57

标签: python c arrays python-2.7 ctypes

我正在尝试将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中的列表列表制作数组,但我无法将其转换为c通过ctypes可用的任何有用的东西。

如何在不修改c代码的情况下从python中调用此函数?任何帮助将不胜感激,也让我知道我是否应该学习c并尝试用c或Cython编写我的程序。 Ctypes可能不是最好的方法。

1 个答案:

答案 0 :(得分:0)

该行:

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

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

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

但即便如此,您也不需要 AINarray 包装器。根据{{​​3}},您可以执行以下操作:

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