Размер типов

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

Размер типов

Сообщение Debugger » 30.06.2011 (Чт) 19:55

Код: Выделить всё
Option Explicit

Private Type SomeType
    Str As String * 8
    Flt As Single
End Type

Private Sub Form_Load()
    Dim data(1) As SomeType
    Debug.Print Len(data(0)), VarPtr(data(0)), VarPtr(data(1))
End Sub

Выводит
Код: Выделить всё
12            2067664       2067684

Правильно, размер типа - 12 байт. Но почему между двумя элементами массива дырка аж 20?
Кстати, если заменить Str As String*8 на b(7) As Byte, то между двумя элементами будет 12 байт, как и положено. Откуда лишних 8 байт?

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

Re: Размер типов

Сообщение Хакер » 30.06.2011 (Чт) 19:57

Потому что реальный размер — 20. 16 — первое поле, 4 — второе.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Размер типов

Сообщение Debugger » 30.06.2011 (Чт) 20:02

Тогда почему Len выводит 12?
В памяти лежат 8 байт строки, 4 байта float и ещё 8 - чего-то непонятного.

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

Re: Размер типов

Сообщение Хакер » 30.06.2011 (Чт) 20:09

Debugger писал(а):В памяти лежат 8 байт строки, 4 байта float и ещё 8 - чего-то непонятного.

Что, неужели даже после этого не доходит?

8 байт строки бы лежало в VB4.
А в VB5 и VB6 — строки юникодные, вообще-то, да :roll:
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Размер типов

Сообщение Debugger » 30.06.2011 (Чт) 20:32

Я всегда думал, что в VB6-юникоде символ занимает два байта и символы идут подряд.
Но почему-то в памяти всё идет в таком порядке (как я уже написал): 8 - строка, 4 байта Flt и в конце - ещё 8. Сначала 8 четных байт юникодной строки, в конце типа - 8 нечетных?
Или это такой хитрый прием для совместимости с ASCII, а заглушка в конце - на случай, если мы вспомним, что на самом деле тип должен весить 20 байт?
У меня это ломает стереотипы и рвет шаблоны.
Последний раз редактировалось Debugger 30.06.2011 (Чт) 20:34, всего редактировалось 1 раз.

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

Re: Размер типов

Сообщение Хакер » 30.06.2011 (Чт) 20:33

Debugger писал(а):Но почему-то в памяти всё идет в таком порядке (как я уже написал): 8 - строка, 4 байта Flt и в конце - ещё 8. Сначала 8 четных байт юникодной строки, в конце - 8 нечетных?

Откуда ты это взял?

У тебя измерения, метод которых вносит недопустимую погрешность в процесс измерения. Это концептуальное понятие.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Размер типов

Сообщение Debugger » 30.06.2011 (Чт) 20:37

Код: Выделить всё
Option Explicit

Private Type SomeType
    Str As String * 8
    Flt As Single
End Type
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Private Sub Form_Load()
    Dim data(1) As SomeType
    Dim b(1 To 20) As Byte, c As Integer
    Debug.Print Len(data(0)), VarPtr(data(1)) - VarPtr(data(0))
    data(0).Str = "test str"
    CopyMemory b(1), data(0), 20
    For c = 1 To 20
        Debug.Print b(c), Chr(b(c))
    Next
End Sub


Код: Выделить всё
12            20
116          t
101          e
115          s
116          t
32           
115          s
116          t
114          r
0             
0             
0             
0             
192          А
62           >
25           
0             
212          Ф
62           >
25           
0             

Может быть, я что-то не так делаю?

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

Re: Размер типов

Сообщение Хакер » 30.06.2011 (Чт) 20:48

Ну всем же известно, что вызовы через Declare устроены таким образом, что при оформлении вызова генерируется код, который переводит все исходящие строки из юникода в ANSI, а всех входящие — наоборот.

Но если b(1) заменить на ByVal VarPtr(b(1)) магия от VB обламается, потому что VarPtr — тот же Any-аргумент, но функция объявлена не через Declare, а через TLB.
Тот же результат будет, если не использовать VarPtr, а использовать текущий код, но CopyMemory объявить в TLB.

Правильные ребята поступают так: не делают никаких CopyMemory, а делают MsgBox Hex(VarPtr(b(1))). Когда ожидаемый бокс появятся, они копируют из него адрес, открывают OllyDbg, и смотрят дамп о указанному (в боксе) адресу.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Размер типов

Сообщение Debugger » 30.06.2011 (Чт) 21:01

И вправду!
Спасибо!

NashRus
Постоялец
Постоялец
 
Сообщения: 388
Зарегистрирован: 18.03.2006 (Сб) 1:16

Re: Размер типов

Сообщение NashRus » 01.07.2011 (Пт) 4:11

Код: Выделить всё
Debug.Print LenB(data(0)) ' 20


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

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

Сейчас этот форум просматривают: AhrefsBot, Yandex-бот и гости: 58

    TopList