Python ctypes: вызов функции с пользовательскими типами в c - PullRequest
0 голосов
/ 24 апреля 2018

Я пытаюсь обернуть существующий код c для использования в Python в Linux. У меня мало опыта работы с c, и в настоящее время я подхожу к этой проблеме, используя ctypes. Моей функции C требуется 2d массив с записями пользовательских типов, и я не знаю, как воссоздать это в 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 - целым числом. Я следовал за старым вопросом относительно многомерных массивов и пытался создать структуру, подобную той, что в коде 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.

Как я могу вызвать эту функцию из python без изменения кода на c? Любая помощь будет высоко ценится, а также дайте мне знать, если я должен просто изучить c и попытаться написать свою программу на c или Cython. Ctypes, возможно, не лучший способ сделать это.

1 Ответ

0 голосов
/ 25 апреля 2018

Линия:

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

должно вызвать TypeError , поскольку вы создаете экземпляр Calibration_AIN . Я считаю, что вы имели в виду:

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

Но даже в этом случае вам не нужна оболочка AINarray . Согласно [Python]: массивы , вы можете сделать что-то вроде:

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
...