Выравнивание структур в VB.

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
keks-n
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2509
Зарегистрирован: 19.09.2005 (Пн) 17:17
Откуда: г. Москва

Выравнивание структур в VB.

Сообщение keks-n » 06.11.2006 (Пн) 21:26

Код: Выделить всё
Option Explicit
Private Type Test
b1 As Byte
b2 As Byte
dw As Long
End Type
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Sub Main()
Dim bt(5) As Byte, t As Test
bt(2) = 1
bt(3) = 1
CopyMemory t, bt(0), 6
MsgBox t.b1 & " " & t.b2 & " " & t.dw & vbCrLf + "Куда подевалась единица?", vbQuestion, "Help!"
End Sub


У меня 3-ий и 4-ый байты почему-то не желают входить в структуру. Выложенный код выдал нули. Реально в памяти она занимает 8 байт, вместо положенных 6.То есть между b2 и dw 2 байта не входящих в структуру, видимо использованных, для выравнивания до DWORD. Если мне не изменяет память, то так быть не должно. Похоже на покарябанность Basic'а на моём компе, иначе объяснить не могу.

Почему так?
Последний раз редактировалось keks-n 06.11.2006 (Пн) 21:30, всего редактировалось 1 раз.
Изображение

_ae_
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 165
Зарегистрирован: 08.10.2006 (Вс) 14:37

Сообщение _ae_ » 06.11.2006 (Пн) 21:29

Реально в памяти она занимает 8 байт, вместо положенных восьми
Что? :lol:
А если серьезно - видимо в VB элементы структуры выравниваются на 2-байтовую границу

keks-n
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2509
Зарегистрирован: 19.09.2005 (Пн) 17:17
Откуда: г. Москва

Сообщение keks-n » 06.11.2006 (Пн) 21:30

Тьфу. Очепятка. Там 6 должно быть. А присутствует 8.
Изображение

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Re: Выравнивание структур в VB.

Сообщение GSerg » 06.11.2006 (Пн) 21:42

keks-n писал(а):Почему так?

Потому что RTFM.
Структуры VB выровнены на 4 байта.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

_ae_
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 165
Зарегистрирован: 08.10.2006 (Вс) 14:37

Re: Выравнивание структур в VB.

Сообщение _ae_ » 06.11.2006 (Пн) 21:54

GSerg писал(а):
keks-n писал(а):Почему так?

Потому что RTFM.
Структуры VB выровнены на 4 байта.

А почему это FM не соотносится с таким простым кодом:
Код: Выделить всё
Private Type T1
    I1 As Integer
    I2 As Integer
    I3 As Integer
End Type

Private Sub Form_Load()
    Dim A As T1
    MsgBox Len(A)=6
End Sub
:?:

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 06.11.2006 (Пн) 21:56

И что же здесь не соотносится?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

_ae_
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 165
Зарегистрирован: 08.10.2006 (Вс) 14:37

Сообщение _ae_ » 06.11.2006 (Пн) 22:02

OK, что есть "выровнены на 4 байта"? dword-aligment или чтото другое?

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 06.11.2006 (Пн) 22:06

Ну да. А что ещё?
Или ты думал, что структура из 4 одиночных байт при выравнивании на 4 имела бы размер 16 байт? А она таки 4.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

_ae_
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 165
Зарегистрирован: 08.10.2006 (Вс) 14:37

Сообщение _ae_ » 06.11.2006 (Пн) 22:21

Честно говоря, я чего-то не понимаю
Код: Выделить всё
#include<iostream>
using namespace std;

#pragma pack(1)

struct A
{
   short a;
   char b;
   short c;
};

#pragma pack(2)

struct B
{
   short a;
   char b;
   short c;
};

#pragma pack(4)

struct C
{
   short a;
   char b;
   short c;
};

#pragma pack(8)

struct D
{
   short a;
   char b;
   short c;
};

void main()
{
   cout<<sizeof(A)<<endl<<sizeof(B)<<endl<<sizeof(C)<<endl<<sizeof(D);
   cin.getline(new char[100],100);
}
В приведенном коде получается 5 6 6 6
А на что тогда влияют цифры 2,4,8 ?

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 07.11.2006 (Вт) 4:56

Смысл выравнивания в том, что каждое поле выравнивается на min(размер поля, размер выравнивания).
Изображение

_ae_
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 165
Зарегистрирован: 08.10.2006 (Вс) 14:37

Сообщение _ae_ » 07.11.2006 (Вт) 10:13

tyomitch
Если так, то получается, что именно
структура из 4 одиночных байт при выравнивании на 4 имела бы размер 16 байт
:?:

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 07.11.2006 (Вт) 10:15

min(1, 4) = 1, _ae_.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

_ae_
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 165
Зарегистрирован: 08.10.2006 (Вс) 14:37

Сообщение _ae_ » 07.11.2006 (Вт) 10:18

аааа
Спасибо, прояснили ситуацию :)

keks-n
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2509
Зарегистрирован: 19.09.2005 (Пн) 17:17
Откуда: г. Москва

Сообщение keks-n » 07.11.2006 (Вт) 16:48

Получается, что из-за этого выранивания я не могу корректно скопировать данные из массива в структуру? А ежели в TLB объявить, как в сишных хеадерах, то пробелы между элементами исчезнут?
Изображение

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 07.11.2006 (Вт) 16:51

Не "исчезнут", а будут те, которые укажешь.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Сообщение pronto » 07.11.2006 (Вт) 19:17

Чтобы узнать количество байт занимаемых переменной, используйте функцию LenB(Имя_переменной)
O, sancta simplicitas!

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 07.11.2006 (Вт) 19:24

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

Из какого такого массива?
В массиве все элементы имеют одинаковый тип. А в структуре нет.
Изображение

keks-n
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2509
Зарегистрирован: 19.09.2005 (Пн) 17:17
Откуда: г. Москва

Сообщение keks-n » 08.11.2006 (Ср) 16:25

Это плохо :( То есть, надо поэлементно копировать... В этом плане VB.NET даже лучше - позволяет жёстко задать смещение относительно начала структуры.
Изображение

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 08.11.2006 (Ср) 16:56

А какое это имеет отношение к типам?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 08.11.2006 (Ср) 19:53

keks-n писал(а):Это плохо :( То есть, надо поэлементно копировать... В этом плане VB.NET даже лучше - позволяет жёстко задать смещение относительно начала структуры.

Да что ты такое несёшь? смысл от меня полностью ускользает.
Когда может понадобиться копировать массив в структуру и обратно? при том, что в массиве элементы всегда однородные, а в структуре -- всегда разнородные.
Если в структуре все элементы однородные, то выравнивания как бы нет.
Изображение

keks-n
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2509
Зарегистрирован: 19.09.2005 (Пн) 17:17
Откуда: г. Москва

Сообщение keks-n » 08.11.2006 (Ср) 20:27

Фишка в чём - гружу полностью некий файл в массив и пытаюсь из массива выделить структуры. Нарываюсь на пробелы между членами типа. Иду сюда. Вот и вся история.
Изображение

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 09.11.2006 (Чт) 8:07

а сразу в структуры (в массив структур) прочитать по каким то причинам нельзя?
Весь мир матрица, а мы в нем потоки байтов!

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Сообщение Ennor » 09.11.2006 (Чт) 13:03

Ну или забить в структуру padding-члены. Штатная практика, вообще-то.


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

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

Сейчас этот форум просматривают: Mail.ru [бот], Yandex-бот и гости: 105

    TopList