Ожидаемый экземпляр LP_c_short вместо _ctypes.PyCStructType

В программном обеспечении, созданном кем-то другим, у меня есть эта функция:

Result = GetStatusDownloadFile(self.server,pState,progress)

который по описанию должен возвращать статус и текущий прогресс загрузки файла, но при его выполнении пишет:

ctypes.ArgumentError: argument 2: TypeError: expected LP_c_short instance instead of _ctypes.PyCStructType

Насколько я понимаю, ошибка в файле pState. В руководстве я видел, что оно определяется как перечисление

typedef enum {
Error                = -1,
Inactive                = 0,
Config                = 1,
ListenBootMode        = 2,
ClearPattern                = 3,
SetBank                = 4,
ListenBank                = 5,
EraseFlash                = 6,
ListenErased                = 7,
Load                = 8,
Loading                = 9,
Terminate                = 10,
Successful                = 11,

}

Поэтому я подумал, что мне следует определить его в виде структуры вроде

class pState(Structure):
_fields_ = [("Error", c_short), ("Inactive", c_short), ("Config", c_short),
            ("ListenBootMode", c_short), ("ClearPattern", c_short),("SetBank", c_short),
            ("ClearPattern", c_short),("ListenBank", c_short),("EraseFlash", c_short),("Load", c_short),
            ("Loading", c_short),("Terminate", c_short),("Successful", c_short)]

Но я понятия не имею, как «конвертировать» его в LP_c_short

[ТАК]: Как создать минимальный воспроизводимый пример (reprex (mcve)). Добавьте код (C и Python), ожидаемые и фактические результаты.
CristiFati 10.05.2024 18:43
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
1
67
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Судя по сообщению об ошибке, функция ожидает C-эквивалент short* для второго параметра и, похоже, использует его в качестве выходного параметра. Создайте экземпляр ctypes.c_short и передайте его по ссылке в функцию, а затем извлеките возвращаемое значение. Это будет целое число, соответствующее одному из значений перечисления.

import ctypes as ct

ERROR = -1
INACTIVE = 0
CONFIG = 1
LISTENBOOTMODE = 2
CLEARPATTERN = 3
SETBANK = 4
LISTENBANK = 5
ERASEFLASH = 6
LISTENERASED = 7
LOAD = 8
LOADING = 9
TERMINATE = 10
SUCCESSFUL = 11

state = ct.c_short()
... # missing code defining GetStatusDownloadFile, self.server, and progress
result = GetStatusDownloadFile(self.server, ct.byref(state), progress)
if state.value == SUCCESSFUL:
    ...

Я предпринял попытку и напечатал результат ct.byref(state), получив следующее: <cparam 'P' (0x03BCD130)>, можете ли вы объяснить мне, как интерпретировать этот вывод?

martinmistere 13.05.2024 08:28

@martinmistere Это более эффективный способ передачи параметров указателя, чем создание реального типа pointer. См. по ссылке. Он используется для передачи указателя на функцию. На дисплее просто указано, что это указатель.

Mark Tolonen 13.05.2024 08:46
print(state.value), чтобы увидеть обновленное значение после вызова функции.
Mark Tolonen 13.05.2024 08:53

Другие вопросы по теме