Переопределение структуры

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

Переопределение структуры

Сообщение Sun07 » 28.05.2006 (Вс) 23:43

В файле записана инф-я определённой структуры. Необходимо добавить в структуру несколько полей. Читаю инф-ю в массив со старой структурой и надо записать инф-ю в новую структуру. Подскажите, как разом присвоить значения одноимённых полей старой структуры новой структуре (структура большая, присваивать вручную неудобно), например:

Private Type MyStru
num1 as long
num2 as byte
...
num1000 as byte
End Type

Private Type NewMyStru
num1 as long
num2 as byte
...
num1000 as byte
num1001 as integer 'новое поле
End Type

dim a_new() as NewMyStru, a() as MyStru

'ручное присвоение, а надо заменить автоматом
a_new(1).num1=a(1).num1
a_new(1).num2=a(1).num2
...

Amed
Алфизик
Алфизик
 
Сообщения: 5346
Зарегистрирован: 09.03.2003 (Вс) 9:26

Сообщение Amed » 28.05.2006 (Вс) 23:50

CopyMemory.

Сейчас попробую.

Amed
Алфизик
Алфизик
 
Сообщения: 5346
Зарегистрирован: 09.03.2003 (Вс) 9:26

Сообщение Amed » 28.05.2006 (Вс) 23:54

Код: Выделить всё
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)

Private Type Struct
    Num1 As Long
    Num2 As Byte
End Type

Private Type NewStruct
    Num1 As Long
    Num2 As Byte
    Num3 As Integer
End Type

Private Sub Form_Load()
Dim a As Struct, b As NewStruct

a.Num1 = 1
a.Num2 = 2

MsgBox "a.Num1=" & a.Num1 & vbCrLf & "a.Num2=" & a.Num2

CopyMemory b, a, Len(a)

MsgBox "b.Num1=" & b.Num1 & vbCrLf & "b.Num2=" & b.Num2
End Sub


Учти, что новые поля в новой структуре должна быть объявлены в конце.

Sun07
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 355
Зарегистрирован: 17.02.2006 (Пт) 21:27

Сообщение Sun07 » 29.05.2006 (Пн) 1:08

спасибо, Amed!

Sun07
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 355
Зарегистрирован: 17.02.2006 (Пт) 21:27

Сообщение Sun07 » 29.05.2006 (Пн) 1:19

а как можно полностью удалить массив из памяти? ReDim() - ошибка, ReDim(0) - остаётся один элемент

Amed
Алфизик
Алфизик
 
Сообщения: 5346
Зарегистрирован: 09.03.2003 (Вс) 9:26

Сообщение Amed » 29.05.2006 (Пн) 1:51

Erase

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

Сообщение GSerg » 29.05.2006 (Пн) 4:23

Вообще-то, для присвоения структур есть оператор lset... В примере Amed'а, это было бы lset b=a...
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

BV
Thinker
Thinker
Аватара пользователя
 
Сообщения: 3987
Зарегистрирован: 12.09.2004 (Вс) 0:55
Откуда: Молдавия, г. Кишинёв

Сообщение BV » 29.05.2006 (Пн) 5:23

Вообще-то, оператор LSet выравнивает строку по левому краю, заполняя остальное пробелами. Неужели он и структуры присваивать умеет?
const char *out = "|*0>78-,+<|"; size_t cc = char_traits<char>::length(out);
for (size_t i=0;i<cc;i++){cout<<static_cast<char>((out[i]^89));}cout<<endl;

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 29.05.2006 (Пн) 7:11

BV писал(а):Неужели он и структуры присваивать умеет?

Умеет.
Lasciate ogni speranza, voi ch'entrate.

Sun07
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 355
Зарегистрирован: 17.02.2006 (Пт) 21:27

Сообщение Sun07 » 06.06.2006 (Вт) 1:23

У меня не получается. Данные сдвигаются. Думаю, что массивы не всегда занимают подряд идущие ячейки памяти. Как массив A так и массив B из примера Ameda. Lset мне не подходит, т.к. надо скопировать в массив B пользовательской структуры массив А(n) байт (скопировать побайтово). Что делать?

Sun07
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 355
Зарегистрирован: 17.02.2006 (Пт) 21:27

Сообщение Sun07 » 06.06.2006 (Вт) 1:37

или же в описании пользовательской структуры существует выравнивание по кол-ву байт, т.е в памяти массива пользовательской структуры есть незначащие байты, у меня выпал 13-й байт! :)

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

Сообщение GSerg » 06.06.2006 (Вт) 6:05

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

Sun07
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 355
Зарегистрирован: 17.02.2006 (Пт) 21:27

Сообщение Sun07 » 06.06.2006 (Вт) 8:43

каким образом осуществляется выравнивание? Как насчёт непрерывности массива в памяти?

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

Сообщение tyomitch » 06.06.2006 (Вт) 8:48

Массив непрерывен в памяти.
Выравнивание, добавляемое в структуру, является частью этой структуры, а не "зазором" между элементами массива.
Изображение

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

Сообщение Viper » 06.06.2006 (Вт) 8:48

Выравнивание осуществляется по границе 4-х байт, а массивы в памяти непрерывны.

[edit]
для иллюстрации выранивания попробуй выполнить такой код:
Код: Выделить всё
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Type MyStruct
    b As Byte
    i As Integer
    l As Long
End Type
Public Sub main()
Dim ms As MyStruct
Debug.Print Len(ms)
Debug.Print LenB(ms)
ms.b = &HFF
ms.i = &HAAAA
ms.l = &HBBBBBBBB
Dim b(0 To 7) As Byte
CopyMemory b(0), ms, 8
Dim i As Integer
For i = 0 To 7
    Debug.Print "&H" & Hex(b(i))
Next i
End Sub

[/edit]
Весь мир матрица, а мы в нем потоки байтов!

Sun07
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 355
Зарегистрирован: 17.02.2006 (Пт) 21:27

Сообщение Sun07 » 07.06.2006 (Ср) 0:55

Да, вот это я попал... Ну и зачем нужно это выравнивание? Хотя есть ещё надежда. Может можно использовать часть структуры, т.е. можно ли объявить переменную программно (не явно), размером части структуры. Например, у меня была структура длиной 40 байт, я добавляю к ней ещё 20 байт в КОНЕЦ и получаю новую структуру. Могу я объявить ПРОГРАММНО переменную пользовательского типа размером 40 байт по старой структуре, не описанной ЯВНО в новой структуре (т.е. у меня в файле хранится только размер старой структуры, я его читаю и от него пляшу). Или можно поступить по другому? Тогда можно было бы использовать LSet!

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

Сообщение GSerg » 07.06.2006 (Ср) 5:19

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

Sun07
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 355
Зарегистрирован: 17.02.2006 (Пт) 21:27

Сообщение Sun07 » 08.06.2006 (Чт) 1:27

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

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

Сообщение GSerg » 08.06.2006 (Чт) 5:11

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

Sun07
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 355
Зарегистрирован: 17.02.2006 (Пт) 21:27

Сообщение Sun07 » 08.06.2006 (Чт) 23:57

Подскажите, можно ли обращаться к данным в структуре по смещению, вроде Dim a as MyStruc, a.[Name1+5]=... на VisualBasic 6?

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

Сообщение GSerg » 09.06.2006 (Пт) 5:40

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

Sun07
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 355
Зарегистрирован: 17.02.2006 (Пт) 21:27

Сообщение Sun07 » 09.06.2006 (Пт) 11:29

а вот интересно, как обстоят дела с добавлением полей в базах данных ADO?

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

Сообщение GSerg » 09.06.2006 (Пт) 11:32

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

Sun07
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 355
Зарегистрирован: 17.02.2006 (Пт) 21:27

Сообщение Sun07 » 09.06.2006 (Пт) 11:54

ну работа с базами через ADO

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

Сообщение GSerg » 09.06.2006 (Пт) 11:56

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


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

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

Сейчас этот форум просматривают: AhrefsBot и гости: 14

    TopList  
cron