Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 2, 2009 13:42:37

bialix
От:
Зарегистрирован: 2006-07-13
Сообщения: 774
Репутация: +  1  -
Профиль   Отправить e-mail  

Как при помощи ctypes читать из массива переменной длины?

Имеется Си объявление:

typedef struct CFMessageBase {
unsigned long msg_code;
unsigned long size;
unsigned char body[1];
} CFMessageBase, *PCFMessageBase;
Член структуры size указывает длину массива body.

Работа с такими структурами ведется в специальной Си-библиотеке. Я делаю обвертку к этой библиотеке при помощи ctypes (на Pyrex не получается, а гольный Python-C API слишком тяжело для меня).

Обвертка выглядит так:

class CFMessageBase(Structure):
_fields_ = [
('msg_code', c_ulong),
('size', c_ulong),
('body', c_uint8 * 1),
]
Теперь ломаю голову как мне вычитывать байты за пределами границ массива body, потому что ctypes строго следит за порядком:

a = CFMessageBase()

print a.body[1]

Traceback (most recent call last):
File "C:\Temp\1\test.py", line 14, in <module>
print a.body[1]
IndexError: invalid index
PS: Boost::Python не предлагать.



Отредактировано (Окт. 2, 2009 13:47:24)

Офлайн

#2 Окт. 2, 2009 15:03:01

pyuser
От:
Зарегистрирован: 2007-05-13
Сообщения: 658
Репутация: +  36  -
Профиль   Отправить e-mail  

Как при помощи ctypes читать из массива переменной длины?

class CFMessageBase(Structure):
_fields_ = [
('msg_code', c_ulong),
('size', c_ulong),
('body', c_ulong),]

a = CFMessageBase()
body = (c_uint8 * a.size).from_address(a.body)
for i in xrange(a.size): print(body[i])



Офлайн

#3 Окт. 2, 2009 15:18:00

bialix
От:
Зарегистрирован: 2006-07-13
Сообщения: 774
Репутация: +  1  -
Профиль   Отправить e-mail  

Как при помощи ctypes читать из массива переменной длины?

body = (c_uint8 * a.size).from_address(a.body[0])
print (body)

<__main__.c_ubyte_Array_4 object at 0x00A9A3A0>
print body[0]
На этом месте получаю segmentation fault.



Офлайн

#4 Окт. 2, 2009 15:23:18

bialix
От:
Зарегистрирован: 2006-07-13
Сообщения: 774
Репутация: +  1  -
Профиль   Отправить e-mail  

Как при помощи ctypes читать из массива переменной длины?

Метод from_address принимает собственно адрес. Непонятно как получить адрес a.body. Функция pointer дает указатель, но не адрес.



Офлайн

#5 Окт. 2, 2009 15:25:25

bialix
От:
Зарегистрирован: 2006-07-13
Сообщения: 774
Репутация: +  1  -
Профиль   Отправить e-mail  

Как при помощи ctypes читать из массива переменной длины?

pyuser
class CFMessageBase(Structure):
_fields_ = [
('msg_code', c_ulong),
('size', c_ulong),
('body', c_ulong),]

a = CFMessageBase()
body = (c_uint8 * a.size).from_address(a.body)
for i in xrange(a.size): print(body[i])
Ваш код не работает. a.body – это значение, а не адрес.



Офлайн

#6 Окт. 2, 2009 15:31:35

pyuser
От:
Зарегистрирован: 2007-05-13
Сообщения: 658
Репутация: +  36  -
Профиль   Отправить e-mail  

Как при помощи ctypes читать из массива переменной длины?

видимо я чего-то не понимаю, почему:

body = (c_uint8 * a.size).from_address(a.body[0]) # ???
атрибут body структуры обычный указатель поэтому я и объявил его как c_ulong



Офлайн

#7 Окт. 2, 2009 15:36:45

bialix
От:
Зарегистрирован: 2006-07-13
Сообщения: 774
Репутация: +  1  -
Профиль   Отправить e-mail  

Как при помощи ctypes читать из массива переменной длины?

потому что атрибут body не является указателем. это массив байт.



Офлайн

#8 Окт. 2, 2009 15:55:58

bialix
От:
Зарегистрирован: 2006-07-13
Сообщения: 774
Репутация: +  1  -
Профиль   Отправить e-mail  

Как при помощи ctypes читать из массива переменной длины?

a2 – это не массив, а только указатель на данные. А a1 – это живой массив.

Вы путаете имя массива с указателями.



Офлайн

#9 Окт. 2, 2009 16:08:21

pyuser
От:
Зарегистрирован: 2007-05-13
Сообщения: 658
Репутация: +  36  -
Профиль   Отправить e-mail  

Как при помощи ctypes читать из массива переменной длины?

есть функция addressof

body = (c_uint8 * a.size).from_address(addressof(a.body))



Офлайн

#10 Окт. 2, 2009 16:16:58

bialix
От:
Зарегистрирован: 2006-07-13
Сообщения: 774
Репутация: +  1  -
Профиль   Отправить e-mail  

Как при помощи ctypes читать из массива переменной длины?

точно, addressof помогла. работает.

Давно я на ctypes ничего не делал, позабывал всё.

pyuser – спасибо!



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version