Intereting Posts
Почему gcc переупорядочивает локальную переменную в функции? Почему «для (i = 0,1; i! = 1,0; i + = 0,1)» не нарушается при i = 1,0? Значения по умолчанию для аргументов в функциях C и перегрузка функций в C Могут ли локальные переменные и функции иметь одинаковые имена в C? повреждение памяти Может ли Mac OS X El Capitan запускать программное обеспечение, скомпилированное для Yosemite, которое ожидает библиотеки в / usr / gnu64 / lib? Как MPI_IN_PLACE работает с MPI_Scatter? Как выполнить программу из дескриптора файла? Использование Перейти к существующему проекту C Задача программирования C, исходный файл html Являются ли несколько realloc более дорогими, чем огромный malloc? Как компоновщики решают разрешенные глобальные символы в C Представление float в C Синтаксис указателя в C: почему * применяется только к первой переменной? Чтобы спать на C, следует ли использовать часы с часами или системный вызов?

Ctypes: отображение возвращаемого указателя на структуру

Я пробовал читать все вопросы / ответы по этой теме, но я не мог заставить работать. Все, что я пытаюсь сделать, это отправить структуру для общего объекта, а затем вернуть ее и быть доступной.

Мне удалось создать структуру ОК, и я могу передать ее в общий объект. Я знаю это, поскольку он отлично работает, возвращая определенное значение из структуры. Определение структуры в Python можно увидеть ниже:

class ROW(ctypes.Structure): _fields_ = [("Address",ctypes.c_int16), ("FirstRegister",ctypes.c_int16), ("NumberOfRegisters",ctypes.c_int16), ("Sampling", ctypes.c_int16)] class CONNECTOR(ctypes.Structure): _fields_ = [("NumberOfRows", ctypes.c_int16), ("Rows", ROW * 200)] # Initialise an array of connectors (CON1, CON2, CON11, CON12) ConArray = CONNECTOR * 4 con = ConArray() # Initialise an array of ROW struct RowArray = ROW * 200 row = RowArray() 

Затем я заполняю структуру данными из базы данных SQLite и могу получить доступ к конкретным данным, используя con[n].Rows[m].Address и т. Д.

В настоящее время я пытаюсь просто отправить один коннектор за один раз и вернуть ту же структуру.

Соответствующий код можно увидеть ниже:

 testlib = ctypes.cdll.LoadLibrary('_example.so') x = testlib.square_array x.argtype = ctypes.POINTER(CONNECTOR) x.restype = ctypes.POINTER(CONNECTOR) y = x(ctypes.byref(con[0])) 

Я пробовал много разных методов вызова функции, но этот, по-видимому, является наиболее перспективным. Проблема в том, что когда я пытаюсь получить доступ к определенным значениям с помощью y.Rows[0].Address[0] , возникает ошибка: AttributeError: 'LP_CONNECTOR' object has no attribute 'Rows' .

Если вместо этого я просто вызываю функцию напрямую:

 x = testlib.square_array(ctypes.byref(con[0])) 

Я получаю int который я предполагаю, представляет собой адрес памяти, например: 35664848 .

Я пробовал всевозможные варианты, но я совершенно не знаком с C (коллега будет обрабатывать всю C-часть кода). Есть ли предлагаемые решения? Мне кажется, что я просто пропустил одну маленькую вещь, но мне потребовалось много дней, чтобы достичь этой цели.

Обновление: добавлен код C

Код C можно увидеть ниже:

example.c:

  #include "example.h" CONNECTOR* square_array(CONNECTOR* con) { printf("Value of Row 0 Address%i\n",con->Rows[0].Address); return (con); } 

example.h:

 struct ROW; struct CONNECTOR; typedef struct { short int Address; short int FirstRegister; short int NumberOfRegisters; short int Sampling; }ROW; typedef struct { short int NumberOfRows; ROW Rows[200]; }CONNECTOR; CONNECTOR Connectors[4]; 

Я уже создал небольшой собственный пример. После более пристального изучения кода Python я мог бы определить заголовок функции (и я также добавил некоторое фиктивное тело).

Проблема проста, функция возвращает указатель CONNECTOR , чтобы получить доступ к своим членам, вам нужно сначала «разыменовать» его, иначе вы получите AttributeError . Вот ваш код (немного измененный):

 testlib = ctypes.cdll.LoadLibrary("_example.so") testfunc = testlib.square_array testfunc.argtype = ctypes.POINTER(CONNECTOR) testfunc.restype = ctypes.POINTER(CONNECTOR) pconnector0 = testfunc(ctypes.byref(con[0])) connector0 = pconnector0.contents print(connector0.NumberOfRows) print(connector0.Rows[0].Address) 

«Секрет» заключается в pconnector0.contents который выполняет «разыменование».

В качестве побочного примечания строка кода y.Rows[0].Address[0] вызовет TypeError из-за [0] в конце: Address является int и не может быть проиндексирован (не определяет __getitem__ ) ,

Что касается второго подхода (вызов функции напрямую), это та же проблема. Вот какой рабочий код:

 pconnector1 = testlib.square_array(ctypes.byref(con[0])) connector1 = pconnector1.contents print(type(connector1)) 

Примечание . Я использовал Python 2.7.10 на Win10 x64 , но здесь не должно быть Python версии или конкретной платформы.