Невыровненные типы в VB!?

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
0xy
Бывалый
Бывалый
 
Сообщения: 223
Зарегистрирован: 14.06.2006 (Ср) 2:34

Невыровненные типы в VB!?

Сообщение 0xy » 28.06.2011 (Вт) 2:03

Код: Выделить всё
Type USER_TYPE
   A As Byte
   B As Integer
End Type
Dim UserVar As USER_TYPE

Declare Function WinApi& Lib "kernel32" (UserVar As ANY)

При вызове, функции передается структура, отличная от USER_TYPE, а имено:

A As Byte
X3 As Byte
B As Integer

со всеми вытекающими! :(

Это возможно как-то побороть?
Последний раз редактировалось 0xy 28.06.2011 (Вт) 4:13, всего редактировалось 4 раз(а).

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Невыровненные типы в VB!?

Сообщение ger_kar » 28.06.2011 (Вт) 7:30

А реальный пример можно? Точнее не пример, а реальный кусок кода с вызовом реальной ф-ции, а не абстрактного WinApi& ? В предложенном примере структура формируется вполне нормально. Я даже сделал тестовую DLL заглушку на основе кирпича Хакера с FNDLL и с такой же структурой, туда все нормально передается.
А вообще совет - сам еще раз внимательно посмотри на свой код, причем обращая внимание на мелочи, правильность символов, тип передачи (по ссылке byRef или по значению byVal). Мне шестое чувство подсказывает, что дело именно в мелочи, которая при просмотре кода почти неуловима, но отравляет бытие программиста ;) viewtopic.php?f=9&t=43275#p6755399
Бороться и искать, найти и перепрятать

0xy
Бывалый
Бывалый
 
Сообщения: 223
Зарегистрирован: 14.06.2006 (Ср) 2:34

Re: Невыровненные типы в VB!?

Сообщение 0xy » 28.06.2011 (Вт) 7:52

Код: Выделить всё
Type USB_DEVICE_DESCRIPTOR
bLength            As Byte
bDescriptorType    As Byte
bcdUSB             
bDeviceClass       As Byte
bDeviceSubClass    As Byte
bDeviceProtocol    As Byte
bMaxPacketSize0    As Byte
idVendor           As Integer
idProduct          As Integer
bcdDevice          As Integer
iManufacturer      As Byte
iProduct           As Byte
iSerialNumber      As Byte
bNumConfigurations As Byte
End Type

Type USB_ENDPOINT_DESCRIPTOR
bLength          As Byte
bDescriptorType  As Byte
bEndpointAddress As Byte
bmAttributes     As Byte
wMaxPacketSize   As Integer
bInterval        As Byte
End Type

Type USB_PIPE_INFO
EndpointDescriptor As USB_ENDPOINT_DESCRIPTOR
ScheduleOffset     As Long                   
End Type

Type USB_NODE_CONNECTION_INFORMATION
ConnectionIndex           As Long           
DeviceDescriptor          As USB_DEVICE_DESCRIPTOR '18 байт
CurrentConfigurationValue As Byte       
LowSpeed                  As Byte               
DeviceIsHub               As Byte               
DeviceAddress             As Integer           
NumberOfOpenPipes         As Long         
ConnectionStatus          As Long             
PipeList(1 To 32)         As USB_PIPE_INFO        '11 байт
End Type

Private Declare Function DeviceIoControl Lib "kernel32" (ByVal hDevice&, ByVal dwIoControlCode&, lpInBuffer As Any, ByVal nInBufferSize&, lpOutBuffer As Any, ByVal nOutBufferSize&, lpBytesReturned As Long, Optional ByVal lpOverlapped&) As Long

Function usbPortEnum(hHub As Long, PortCount As Byte, HubDepth As Long) As Long
Dim ConnectionInformation                     As USB_NODE_CONNECTION_INFORMATION
Dim ConnectionInformation2                     As USB_NODE_CONNECTION_INFORMATION
'........
   Success = DeviceIoControl(hHub, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION, _
                             ConnectionInformation, Len(ConnectionInformation), _
                             ConnectionInformation2, Len(ConnectionInformation), _
                             BytesReturned)
   ConnectionInformation = ConnectionInformation2
   If Success Then
     If ConnectionInformation.ConnectionStatus = 1 Then
'........

В этом месте вместо единицы получаем 117440512.

Содержимое буфера:
Код: Выделить всё
0063ECA8  02 00 00 00 12 01 10 01  ...
0063ECB0  02 00 00 20 9A 06 01 45  .. љE
0063ECB8  01 01 01 02 08 02 01 00  .
0063ECC0  00 02 00 03 00 00 00 01  .....
0063ECC8  00 00 00 07 05 85 03 08  ...…
0063ECD0  00 40 00 00 00 00 07 05  .@....
0063ECD8  81 02 40 00 00 00 00 00  Ѓ@.....
0063ECE0  00 07 05 02 02 40 00 00  .@..
0063ECE8  00 00 00 00 00 00 00 00  ........

т.е. налицо выравнивание VB-шной структуры.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Невыровненные типы в VB!?

Сообщение ger_kar » 28.06.2011 (Вт) 8:31

Код: Выделить всё
Private Declare Function DeviceIoControl Lib "_ernel32"
Почему _ernel32, а не Kernel32 - это что модифицированная библиотека?
Код: Выделить всё
Success = DeviceIoControl(hHub, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION, _ ...
У тебя IOCTL_USB_GET_NODE_CONNECTION_INFORMATION нигде не объявляется и не инициализируется. Ты Option Explicit используешь?
Бороться и искать, найти и перепрятать

0xy
Бывалый
Бывалый
 
Сообщения: 223
Зарегистрирован: 14.06.2006 (Ср) 2:34

Re: Невыровненные типы в VB!?

Сообщение 0xy » 28.06.2011 (Вт) 8:49

С этими двум пунктами все в порядке.
_ernel просто переходник на kernel -- для отладки.
Const IOCTL_USB_GET_NODE_CONNECTION_INFORMATION = 2229260

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Невыровненные типы в VB!?

Сообщение Хакер » 28.06.2011 (Вт) 8:59

0xy писал(а):При вызове, функции передается структура, отличная от USER_TYPE, а имено:

A As Byte
X3 As Byte
B As Integer

со всеми вытекающими! :(

Это возможно как-то побороть?

Только заменив B As Integer на BLow as Byte и BHi As Byte.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

0xy
Бывалый
Бывалый
 
Сообщения: 223
Зарегистрирован: 14.06.2006 (Ср) 2:34

Re: Невыровненные типы в VB!?

Сообщение 0xy » 28.06.2011 (Вт) 9:15

Так я и думал. Жуткий баг, однако :(((

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Невыровненные типы в VB!?

Сообщение Хакер » 28.06.2011 (Вт) 9:20

0xy писал(а):Так я и думал. Жуткий баг, однако :(((

Вовсе нет. VB проектировался в расчёт на кроссплатформенность, а на отличных от x86 архитектурах попытка доступа к невыровненному слову или двойному слову вызывает исключение «нарушение выравнивания».
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

0xy
Бывалый
Бывалый
 
Сообщения: 223
Зарегистрирован: 14.06.2006 (Ср) 2:34

Re: Невыровненные типы в VB!?

Сообщение 0xy » 28.06.2011 (Вт) 9:29

Так прикол в том, что это не мои художества, а структуры USB-запросов.
Любопытно: а как же они на других процах обрабатываются?

0xy
Бывалый
Бывалый
 
Сообщения: 223
Зарегистрирован: 14.06.2006 (Ср) 2:34

Re: Невыровненные типы в VB!?

Сообщение 0xy » 28.06.2011 (Вт) 23:58

В соседней темеотрыл такое:
keks-n писал(а):
А ежели в TLB объявить, как в сишных хеадерах, то пробелы между элементами исчезнут?
GSergb писал(а):Не "исчезнут", а будут те, которые укажешь.

Прошу Хакера прокомментпровать, правда ли сие?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Невыровненные типы в VB!?

Сообщение Хакер » 29.06.2011 (Ср) 0:09

Мне кажется, что нет, но стоит попробовать. В сях это решается pragma-pack-ом, в MIDL-е я аналогичного средства не припомню. Так что я не знаю, что имел в виду GSerg под «какие укажешь», потому что способ указания вроде бы как отсутствует.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Vi
Постоялец
Постоялец
 
Сообщения: 739
Зарегистрирован: 25.01.2002 (Пт) 11:03
Откуда: Россия, Ижевск

Re: Невыровненные типы в VB!?

Сообщение Vi » 29.06.2011 (Ср) 9:32

Хакер писал(а):Мне кажется, что нет, но стоит попробовать. В сях это решается pragma-pack-ом, в MIDL-е я аналогичного средства не припомню. Так что я не знаю, что имел в виду GSerg под «какие укажешь», потому что способ указания вроде бы как отсутствует.

midl /align:alignment
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! (с) КВН

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Невыровненные типы в VB!?

Сообщение Хакер » 29.06.2011 (Ср) 11:48

Vi писал(а):midl /align:alignment

Ну я имел в виду язык MIDL, а не одноимённую утилиту.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Невыровненные типы в VB!?

Сообщение ger_kar » 29.06.2011 (Ср) 17:52

Хакер писал(а):Только заменив B As Integer на BLow as Byte и BHi As Byte.

Т.е. получается, что передача параметров (BLow as Byte, BHi As Byte) и (B As Integer) эквивалентна. Получается, что VB это никак не проверяет, а просто банально упаковывает в стек и вызывается нужная ф-ция, а для ф-ции главное то то, что упаковано в стек. Таким образом и вместо(X as Long) можно запросто передать (X1 as Byte, X2 as Byte, X3 as Byte, X4 as Byte) в нужной последовательности? И еще интересно можно ли вместо этой последовательности байт, передать структуру состоящую из 4 элементов с типом байт?
Бороться и искать, найти и перепрятать

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Невыровненные типы в VB!?

Сообщение Хакер » 29.06.2011 (Ср) 18:13

ger_kar писал(а):Т.е. получается, что передача параметров (BLow as Byte, BHi As Byte) и (B As Integer) эквивалентна

Нет, в стеке всегда выравнивание — 4 байта. Ну, в свете одной соседней темы, можно уточнить, что зависит от флагов в дескрипторе сегмента стека. Но с точки зрения VB6 — это дебри. Выравнивание всегда по 4 байтной границе.

ger_kar писал(а):Получается, что VB это никак не проверяет, а просто банально упаковывает в стек и вызывается нужная ф-ция, а для ф-ции главное то то, что упаковано в стек.

Да любой ЯП так.

ger_kar писал(а):Таким образом и вместо(X as Long) можно запросто передать (X1 as Byte, X2 as Byte, X3 as Byte, X4 as Byte)

Нельзя, потому что функция ожидает 4 байтовый аргументный фрейм, а будет 16-байтовый.

ger_kar писал(а): И еще интересно можно ли вместо этой последовательности байт, передать структуру состоящую из 4 элементов с типом байт?

Нельзя, потому что структуры передаются только ByRef. Придёт адрес структуры с четырьмя байтами, а не сами эти четыре байта.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Невыровненные типы в VB!?

Сообщение ger_kar » 29.06.2011 (Ср) 18:29

Хакер писал(а):Только заменив B As Integer на BLow as Byte и BHi As Byte.

ger_kar писал(а):Т.е. получается, что передача параметров (BLow as Byte, BHi As Byte) и (B As Integer) эквивалентна?

Хакер писал(а):Нет, в стеке всегда выравнивание — 4 байта.

И как же тогда заменять B As Integer на BLow as Byte и BHi As Byte?
Бороться и искать, найти и перепрятать

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Невыровненные типы в VB!?

Сообщение Хакер » 29.06.2011 (Ср) 18:42

ger_kar писал(а):И как же тогда заменять B As Integer на BLow as Byte и BHi As Byte?

Речь же о полях структуры, а не об аргументах функции.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Невыровненные типы в VB!?

Сообщение ger_kar » 29.06.2011 (Ср) 19:01

Блин, точно, что-то совсем мозги переклинило. Думал про одно, а мысль перескочила на другое, да и заклинила :)
Тогда перефразирую вопрос: Структура с одним лонгом и структура с четырмя байтами будут эквивалентны? Имеются ввиду конечно не сами структуры, а дампы памяти где они храняться. Т.е., можно ли провести преобразование простым копированием GetMem4. Можно конечно и LSet использовать. Но если преобразования множественные, то ИМХО лучше юзать GetMem.
Бороться и искать, найти и перепрятать

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Невыровненные типы в VB!?

Сообщение Хакер » 29.06.2011 (Ср) 19:14

ger_kar писал(а):Тогда перефразирую вопрос: Структура с одним лонгом и структура с четырмя байтами будут эквивалентны?

Такое впечатление, что спрашиваешь, заведомо зная, что эквивалентны.
Т.е., можно ли провести преобразование простым копированием GetMem4. Можно конечно и LSet использовать.

GetMem4 быстрее, LSet — обёртка над универсальной __vbaCopyBytes.

Но если преобразования множественные, то ИМХО лучше юзать GetMem.

Для множества, лежащего подряд (в стиле массива) лучше использовать CopyMemory (разом). Ещё можно, и в некоторых случаях наиболее выгодно, использовать один из видов красивых указателей.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Невыровненные типы в VB!?

Сообщение ger_kar » 29.06.2011 (Ср) 19:28

Хакер писал(а):Такое впечатление, что спрашиваешь, заведомо зная, что эквивалентны.

Справшивал, заведомо догадываясь, но догадки-догадками, а лучше спросить и знать твердо. Я не очень силен (а точнее вообще не силен :) ) в том, как VB работает на уровне машинных кодов и заинтересовался этим, только став участником этого форума (можно сказать на днях :) ). Как то до этого думал, что при программировании в VB этого и не требуется, а почитав этот форум и труды его участников как то переосмыслил свое бытие :) .
Бороться и искать, найти и перепрятать

0xy
Бывалый
Бывалый
 
Сообщения: 223
Зарегистрирован: 14.06.2006 (Ср) 2:34

Re: Невыровненные типы в VB!?

Сообщение 0xy » 06.07.2011 (Ср) 11:13

Хакер писал(а):Только заменив B As Integer на BLow as Byte и BHi As Byte.

А можно ли заменить на B (0 to 1) As Byte или на B As String*2?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Невыровненные типы в VB!?

Сообщение Хакер » 06.07.2011 (Ср) 11:26

0xy писал(а):А можно ли заменить на B (0 to 1) As Byte

Можно.

0xy писал(а):или на B As String*2?

Нет! Сколько мне уже раз нужно написать, что строки в VB — юникодные, и на фиксированные строки это тоже распространяется.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 21

    TopList