Struct с другой структурой внутри нее, используя ctypes

Я разрабатываю программное обеспечение для управления храповым механизмом, оно использует dll под названием xpcomlib и имеет примеры использования на C. Я разрабатываю на Python, а для использования DLL я использую ctypes, я смог сделать, например, те же потребности от одного пуанейро к одной структуре, и одна структура имеет другую. Сделаем понятнее.

Вот часть инструкции:

int FAR PASCAL FXPBasicConvFromText(
  const char FAR* szFileOrig, // Source File name will be converted
  const char FAR* szFileDest, // Dest file name will be converted
  CONVFILEFORMAT FAR* pF // Pointer to source file format
);

Аргумент pF - это указатель на структуру типа CONVFILEFORMAT, которая определяет формат исходного файла. cFields Количество полей в исходном файле должно быть от 1 до 10. Для каждого из полей cFields выше у нас есть структура Field, определенная следующим образом:

CONVFILEFORMAT

struct {
   cName [11]     Field name only for conversions with destination file type DBF
   cType          Field type XPFLD_INT, XPFLD_FLO, XPFLD_STR. See XPCOMxx.H.
   cLength        Length of field
   cDec           Number of decimal places used for floating point in file conversion
XPbasic format for DBASE format
} Field [10];

Пример, сделанный в инструкции:

#include <windows.h>
#include <string.h>
#include “xpcom16.h”

char szInFile[20];
char szOutFile[20];
CONVFILEFORMAT fF;

int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    fF.cFields = 3;
    fF.Field[0].cType = XPFLD_STR;
    fF.Field[0].cLength = 80;
    fF.Field[0].cDec = 0;
    fF.Field[1].cType = XPFLD_INT;
    fF.Field[1].cLength = 2;
    fF.Field[1].cDec = 0;
    fF.Field[2].cType = XPFLD_FLO;
    fF.Field[2].cLength = 8;
    fF.Field[2].cDec = 0;
    strcpy(szInFile, “C:\\TRIX\\ARQTXT.DAT”);
    strcpy(szOutFile, “C:\\TRIX\\ARQXPB.DAT”);
    if (FXPBasicConvFromText(szInFile, szOutFile, &fF))
        return FALSE;
    return TRUE;
}

Учитывая это, мне нужно использовать dll в python, пока я сделал это:

class ConvFileField(ctypes.Structure):
    _fields_ = [("cName", ctypes.c_char_p), ("cType", ctypes.c_byte),
                ("cLength", ctypes.c_byte), ("cDec", ctypes.c_byte)]

class Struct(ctypes.Structure):
    _fields_ = [("cFields", ctypes.c_byte), ("Field", ctypes.POINTER(ConvFileField))]

    elems = (ConvFileField * 10)()
    Field = ctypes.cast(elems, ctypes.POINTER(ConvFileField))

formatPointer = ctypes.POINTER(Struct)
formatPointer.cFields = 0 #Works
formatPointer.Field[0].cType = 1 #Doesn't work

Однако я получаю следующую ошибку, в которой говорится, что моя структура не содержит поля Field, а указанный выше cFields работает нормально.

formatPointer.Field[0].cType = 1 AttributeError: type object
'LP_Struct' has no attribute 'Field'

Покажите нам определение структуры CONVFILEFORMAT.

user2357112 supports Monica 25.10.2018 19:56

Это там я напишу это подожди минутку

Anderson Henrique 25.10.2018 19:57

Готово, я поместил текст над структурой, посмотрите пожалуйста

Anderson Henrique 25.10.2018 19:59

Это в лучшем случае фрагмент определения. Пожалуйста, опубликуйте полное определение структуры CONVFILEFORMAT.

user2357112 supports Monica 25.10.2018 20:00

В мануале есть как раз это

Anderson Henrique 25.10.2018 20:02

Похоже, эта библиотека используется почти исключительно в Бразилии. Все, что я могу найти в Интернете, есть на веб-сайтах .br на португальском языке. Я надеялся найти онлайн-документацию, но все, что я нашел, это сообщения на форуме.

user2357112 supports Monica 25.10.2018 20:11

Нет определения структуры CONVFILEFORMAT. Вы только добавили псевдокод / ​​описание. Пожалуйста, добавьте его определение из файла .час. То же самое и для struct Поле. class Struct должен быть class Field. Агрегация - FXPBasicConvFromText -> CONVFILEFORMAT -> Поле (видимо безымянное?). Код Python показывает путаницу.

CristiFati 25.10.2018 20:16

Таким образом, очевидно, что это связано с каким-то аппаратным обеспечением Трикс технологии. Разве у него не было SDK (рядом с инструкцией)? Там вы можете найти файлы .час, которые содержат определения структур.

CristiFati 25.10.2018 20:36
Почему в 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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
8
823
1

Ответы 1

Имея только искаженное, частичное определение одного поля CONVFILEFORMAT, я не могу точно сказать, как определить тот же тип структуры в ctypes. Однако я могу ответить на общий вопрос о том, как обрабатывать типы структур с вложенными структурами, массивами и массивами структур.

Поле структуры формы

struct {
    ...
} Field [10];

является множество, а не указателем. В частности, это поле с именем Field, тип которого представляет собой массив длиной 10 анонимного типа структуры, определенного предыдущей частью struct {...}. Если ваш код ctypes определяет тип элементов Field как ConvFileField, тогда правильное объявление самого поля Field будет

('Field', ConvFileField*10)

в списке _fields_. Если в остальном ваш список _fields_ верен (мы не можем сказать), то правильным объявлением будет

class CONVFILEFORMAT(ctypes.Structure):
    _fields_ = [('cFields', ctypes.c_byte), ('Field', ConvFileField*10)]

Между прочим, ваше поле cName в ConvFileField имеет ту же проблему. cName выглядит как массив длины 11 в фактическом C, но вместо этого вы объявили указатель.

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