Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.63/27: Рейтинг темы: голосов - 27, средняя оценка - 4.63
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443

Как грамотно соединить структуру с массивом?

14.05.2020, 22:07. Показов 5981. Ответов 75
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем здравствуйте!

Дано:
1. структура UDT
2. массив

Требуется соединить их вместе в одном массиве (типа Byte) так, чтобы новый массив начинался с членов данной структуры и продолжался/завершался членами данного массива. Для примера выбраны очень простенькие/маленькие структура и массив, но на самом деле они могут быть очень большими. И ещё условие задачи такое - циклами пользоваться нельзя, а то эдак я и сам могу тренькать, как сказал бы классик

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Option Explicit
 
Private Type MyUDT
  A As Integer
  B As Long
End Type
 
 
Private Sub Command1_Click()
  Dim udt_MyUDT As MyUDT
  Dim arr_Byte_array(1 To 3)  As Byte
  Dim arr_Total_array()  As Byte
 
 udt_MyUDT.A = 1
 udt_MyUDT.B = 2
 
  arr_Byte_array(1) = 3
  arr_Byte_array(2) = 4
  arr_Byte_array(3) = 5
 
 arr_Total_array() = ' ??????????????????????????????????????????????????????????
 
End Sub
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
14.05.2020, 22:07
Ответы с готовыми решениями:

как грамотно соединить в локальную сеть 5 ПК и 3 пятиэтажных дома
День добрый, подскажите как грамотно соединить в локальную сеть 5 ПК и 3 пятиэтажных дома , меня интересует оборудование, где поставить...

Как грамотно электрически и безопасно соединить ПК и ТВ кабелем HDMI-HDMI?
Здравствуйте! Компьютер питается из незаземлённой двухпроводной линии (розетки), видеокарта имеет выход HDMI. TV SMART питается из...

Стек соединить с массивом
Доброе время суток. Добрался я да коллекций. И ту мне попалась задачка из книжки "JAVA Методы программирование": создать в стеке...

75
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 79
14.05.2020, 22:19
Power_Basic, как должны размещаться члены структуры MyUDT? Поскольку при выравнивании членов структуры она будет занимать 8 байт, вместо 6. Второй момент, arr_Byte_array() всегда состоит из фиксированного количества элементов?
Какие типы присутствуют в структуре? Есть ли ссылочные?
0
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
14.05.2020, 23:02  [ТС]
Цитата Сообщение от The trick Посмотреть сообщение
Power_Basic, как должны размещаться члены структуры MyUDT? Поскольку при выравнивании членов структуры она будет занимать 8 байт, вместо 6. Второй момент, arr_Byte_array() всегда состоит из фиксированного количества элементов?
Какие типы присутствуют в структуре? Есть ли ссылочные?
На самом деле, это WAV-заголовок и аудиопоток, записанный в байт-массив.
Чтобы этот новый массив можно было на диск скинуть в виде WAV-файла и/или переконвертировать в MP3-файл прямо в ОЗУ.

Добавлено через 18 минут
Цитата Сообщение от Power_Basic Посмотреть сообщение
Чтобы этот новый массив можно было на диск скинуть в виде WAV-файла и/или переконвертировать в MP3-файл прямо в ОЗУ.
Но это я уже сам буду делать
За границами этой ветки
0
Эксперт по электронике
6808 / 3233 / 337
Регистрация: 28.10.2011
Сообщений: 12,633
Записей в блоге: 7
14.05.2020, 23:07
Цитата Сообщение от Power_Basic Посмотреть сообщение
На самом деле, это WAV-заголовок и аудиопоток, записанный в байт-массив.
Что мешает хранить их по отдельности?
Цитата Сообщение от Power_Basic Посмотреть сообщение
Чтобы этот новый массив можно было на диск скинуть в виде WAV-файла
Сначала записываете в файл заголовок, потом данные. Необязательно хранить их вместе.

Цитата Сообщение от Power_Basic Посмотреть сообщение
переконвертировать в MP3-файл прямо в ОЗУ.
Для этого заголовок не нужен. На входе поток данных WAV, а на выходе данные MP3, пригодные для записи в файл.
1
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
15.05.2020, 00:51  [ТС]
locm, ну мне ещё хочется сейчас попутно "подтянуть" свою технику программирования. Сенйчас на очереди как раз работа с указателями, массивами, адресами памяти и всё такое.

Цитата Сообщение от locm Посмотреть сообщение
Сначала записываете в файл заголовок, потом данные. Необязательно хранить их вместе.
На самом деле, хороший вариант, спасибо за подсказку. Сначала записываем заголовок, а потом делаем APPEND массив, изящно.

Цитата Сообщение от locm Посмотреть сообщение
Для этого заголовок не нужен. На входе поток данных WAV
"Поток данных WAV" и "поток RAW" это одно и то же, получается? А я как раз раздумывал о том, надо ли перед конвертацией присоединять WAV-заголовок. На всякий случай решил научиться делать это "правильно". А то сйчас-то я через строковые переменные это делаю. Ну вот и захотелось узнать другие способы и выбрать из них самый удобный.
0
Эксперт по электронике
6808 / 3233 / 337
Регистрация: 28.10.2011
Сообщений: 12,633
Записей в блоге: 7
15.05.2020, 01:46
Цитата Сообщение от Power_Basic Посмотреть сообщение
"Поток данных WAV" и "поток RAW" это одно и то же, получается?
WAV это как BMP - несжатые данные.

Цитата Сообщение от Power_Basic Посмотреть сообщение
А то сйчас-то я через строковые переменные это делаю.
В заголовке бинарные данные. Строковые переменные не очень подходящие для их хранения.
0
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
15.05.2020, 16:54  [ТС]
Цитата Сообщение от locm Посмотреть сообщение
В заголовке бинарные данные. Строковые переменные не очень подходящие для их хранения.
Ну дык я же потому и спрашиваю, как следут поступать в подобных случаях
Вот очень простая структура и очень простой массив. Как объединить их вместе в новом массиве так, чтобы новый массив начинался с членов (байтов) данной структуры и заканчивался членами "старого" байт-массива. Код требуется написать на Визуальном бейсике без использования операции FOR ... NEXT.
А если это невозможно в принципе, ну тогда меня вполне устроит ответ "миссия невыполнима"
И тогда использование строк останется для меня самым правильным подходом для таких ситуаций.

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Option Explicit
 
Private Type MyUDT
  A As Integer
  B As Long
End Type
 
 
Private Sub Command1_Click()
  Dim udt_MyUDT As MyUDT
  Dim arr_Byte_array(1 To 3)  As Byte
  Dim arr_Total_array()  As Byte
 
 udt_MyUDT.A = 1
 udt_MyUDT.B = 2
 
  arr_Byte_array(1) = 3
  arr_Byte_array(2) = 4
  arr_Byte_array(3) = 5
 
 arr_Total_array() = ' ??????????????????????????????????????????????????????????
 
End Sub
Цитата Сообщение от locm Посмотреть сообщение
В заголовке бинарные данные. Строковые переменные не очень подходящие для их хранения.
Любые данные представляют из себя последовательность байтов в памяти, то же самое можно сказать и о строках. Если мы не собираемся их распечатывать (а мы не собираемся это делать), тогда строки вполне подходят для временного хранения любых последовательностей байтов. Сейчас я делаю так. Но это вовсе не означает, что я как-будто бы агитирую всех поступать точно так же. Совсем наоборот! Я хочу понять, как поступает мейнстрим в таких ситуациях и поступать точно так же.

Добавлено через 12 минут
Цитата Сообщение от locm Посмотреть сообщение
WAV это как BMP - несжатые данные.
Да это понятно. Но мне пока не ясно, требуется ли для тех функций WINAPI, которые вы мне рекомендовали, сначали присоединять к записанному аудиопотоку WAV-заголовок или достаточно только самого сырого потока.
Но в любом случае, ветка создана не для выяснения этого вопроса. Это пратика, а меня сейчас больше интересует теория, а именно работа с памятью, с адресами памяти, со структурами, с массивами и всё такое.

Добавлено через 18 минут
Цитата Сообщение от The trick Посмотреть сообщение
Power_Basic, как должны размещаться члены структуры MyUDT? Поскольку при выравнивании членов структуры она будет занимать 8 байт, вместо 6.
Пусть выравниваются как угодно, это сейчас не принципиально, меня интересует сам подход к решению этого вопроса, а вовсе не мелкие детали.

Цитата Сообщение от The trick Посмотреть сообщение
Второй момент, arr_Byte_array() всегда состоит из фиксированного количества элементов?
Всегда.

Цитата Сообщение от The trick Посмотреть сообщение
Какие типы присутствуют в структуре? Есть ли ссылочные?
Ссылочных нет. Первый тип Integer, второй тип Long.

Ну код же уже написан, требуется только его завершить:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Option Explicit
 
Private Type MyUDT
  A As Integer
  B As Long
End Type
 
 
Private Sub Command1_Click()
  Dim udt_MyUDT As MyUDT
  Dim arr_Byte_array(1 To 3)  As Byte
  Dim arr_Total_array()  As Byte
 
 udt_MyUDT.A = 1
 udt_MyUDT.B = 2
 
  arr_Byte_array(1) = 3
  arr_Byte_array(2) = 4
  arr_Byte_array(3) = 5
 
' здесь какие-то промежуточные операции
 
 arr_Total_array() = ' ??????????????????????????????????????????????????????????
 
End Sub
P.S. По правде сказать, для меня большая неожиданность, что такая вроде бы простая задача оказалась такой сложной.
0
Эксперт по электронике
6808 / 3233 / 337
Регистрация: 28.10.2011
Сообщений: 12,633
Записей в блоге: 7
15.05.2020, 17:00
Цитата Сообщение от Power_Basic Посмотреть сообщение
Вот очень простая структура и очень простой массив.
Если массив статический, просто создаете его в конце структуры.
PureBasic
1
2
3
4
Structure Test
  Wave.WaveFileHeader
  DataArray.a[100] ; Массив с размером 100 байт.
EndStructure
Если динамический, здесь немного сложнее.
На PureBasic код может выглядеть таким образом при размере массива 100 байт.
PureBasic
1
2
3
4
5
6
Structure Test
  Wave.WaveFileHeader
  DataArray.a[0]
EndStructure
 
*p.Test = AllocateMemory(SizeOf(Test) + 100)
Если нужно изменить размер массива скажем на 200 байт, пишем
PureBasic
1
*p = ReAllocateMemory(*p, SizeOf(Test) + 200)
На VB с его концепцией безопасного программирования точно также будет сложнее написать.

Цитата Сообщение от Power_Basic Посмотреть сообщение
Любые данные представляют из себя последовательность байтов в памяти, то же самое можно сказать и о строках.
Если строки нультерминированные 0 в данных завершит строку с потерей части данных и кроме того может привести к утечке памяти.

Цитата Сообщение от Power_Basic Посмотреть сообщение
строки вполне подходят для временного хранения любых последовательностей байтов.
Не содержащих 0.

Цитата Сообщение от Power_Basic Посмотреть сообщение
Но мне пока не ясно, требуется ли для тех функций WINAPI, которые вы мне рекомендовали, сначали присоединять к записанному аудиопотоку WAV-заголовок или достаточно только самого сырого потока.
Заголовок не нужен. Требуется поток данных согласно заполнению структуры WAVEFORMATEX передаваемой функции acmStreamOpen. То есть о формате данных функция получает информацию не из заголовка, а из структуры.
2
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 79
15.05.2020, 17:39
Цитата Сообщение от Power_Basic Посмотреть сообщение
На самом деле, это WAV-заголовок и аудиопоток, записанный в байт-массив.
Чтобы этот новый массив можно было на диск скинуть в виде WAV-файла и/или переконвертировать в MP3-файл прямо в ОЗУ.
Если ты работаешь с WAV (а точнее RIFF) файлом то тебе можно использовать специальные функции, которые автоматически размещают данные внутри RIFF контейнера - mmioOpen, mmioCreateChunk, mmioWrite etc.

Цитата Сообщение от Power_Basic Посмотреть сообщение
"Поток данных WAV" и "поток RAW" это одно и то же, получается? А я как раз раздумывал о том, надо ли перед конвертацией присоединять WAV-заголовок. На всякий случай решил научиться делать это "правильно". А то сйчас-то я через строковые переменные это делаю. Ну вот и захотелось узнать другие способы и выбрать из них самый удобный.
WAV файл это RIFF файл. WAV файл в свою очередь может содержать помимо аудиоданных еще метаданные, как например имя исполнителя, год и т.п.

Цитата Сообщение от Power_Basic Посмотреть сообщение
Ну дык я же потому и спрашиваю, как следут поступать в подобных случаях
Каким образом должны лежать данные? Ты же не сказал в каком формате. В файле и в памяти данные могу располагаться по-разному.

Цитата Сообщение от Power_Basic Посмотреть сообщение
Любые данные представляют из себя последовательность байтов в памяти, то же самое можно сказать и о строках. Если мы не собираемся их распечатывать (а мы не собираемся это делать), тогда строки вполне подходят для временного хранения любых последовательностей байтов. Сейчас я делаю так. Но это вовсе не означает, что я как-будто бы агитирую всех поступать точно так же. Совсем наоборот! Я хочу понять, как поступает мейнстрим в таких ситуациях и поступать точно так же.
Данные всегда бывают в каком-то определенном формате. Строки к примеру могут быть с нуль-терминалом, либо хранить длину, либо еще как. В произвольной структуре строки вообще хранятся в разных местах.

Цитата Сообщение от Power_Basic Посмотреть сообщение
Да это понятно. Но мне пока не ясно, требуется ли для тех функций WINAPI, которые вы мне рекомендовали, сначали присоединять к записанному аудиопотоку WAV-заголовок или достаточно только самого сырого потока.
Если речь идет об ACM функциях, то им нужны заголовки отдельно, данные отдельно.

Цитата Сообщение от Power_Basic Посмотреть сообщение
Пусть выравниваются как угодно, это сейчас не принципиально, меня интересует сам подход к решению этого вопроса, а вовсе не мелкие детали.
Нет, это важный вопрос, поскольку результат разный. Приведенная структура имеет размер 8 байт, хотя поля занимают только 6 байт. Поле B структуры MyUdt находится по смещению 4, хотя поле A имеет размер 2.
Как данные хранятся в файле (некоторые WINAPI требуют данные в таком формате):

Как данные хранятся в памяти (и WINAPI в основном ожидают такие данные, но не всегда):

В каком формате должны быть данные в итоге?

Цитата Сообщение от Power_Basic Посмотреть сообщение
P.S. По правде сказать, для меня большая неожиданность, что такая вроде бы простая задача оказалась такой сложной.
Задача на самом деле очень простая, просто ты нормально не пояснил что ты хочешь в итоге.

locm, тут раздел PureBasic'а? Причем тут этот диалект? Не нужно скатывать и эту тему в обсуждение этого ЯП. Пока предупреждаю.

Цитата Сообщение от locm Посмотреть сообщение
Не содержащих 0.
Нет, мб в PB так, в VB это не так.
1
15.05.2020, 17:45

Не по теме:

Цитата Сообщение от The trick Посмотреть сообщение
locm, тут раздел PureBasic'а? Причем тут этот диалект? Не нужно скатывать и эту тему в обсуждение этого ЯП. Пока предупреждаю.
Я объяснил на примере что имею в виду, иначе могло быть непонятно.
Если хотите перепишите код на VB.

0
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
15.05.2020, 19:06  [ТС]
Цитата Сообщение от The trick Посмотреть сообщение
Нет, это важный вопрос, поскольку результат разный. Приведенная структура имеет размер 8 байт, хотя поля занимают только 6 байт. Поле B структуры MyUdt находится по смещению 4, хотя поле A имеет размер 2.
Как данные хранятся в файле (некоторые WINAPI требуют данные в таком формате):
Цитата Сообщение от The trick Посмотреть сообщение
В каком формате должны быть данные в итоге?
Ну хорошо, если это важно, тогда всё-таки лучше без выравнивания.
В итоге должен получиться вот такой массив байтов:
01, 00, 02, 00, 00, 00, 03, 04, 05.

Но даже если получится вот такой, тогда это тоже будет считаться приемлемым решением:
01, 00, 00, 00, 02, 00, 00, 00, 03, 04, 05.

Добавлено через 10 минут
The trick и locm, большое вам обоим спасибо за советы относительно кодирования аудиопотока. Я очень внимательно и вдумчиво их прочитал, и хотя мне это очень полезно (ну правда очень полезно!), сейчас всё-таки хотелось бы не углубляться в ту сторону, потому что иначе мы слишком сильно отдалимся от главной (узкой) темы, ради которой была создана эта ветка.

Добавлено через 9 минут
Всё-таки есть практика и есть теория. Обычно я стремлюсь поскорее написать программу, чтобы поскорее увидеть рзультат. При таком подходе остаётся много "белых пятен" в изучении теории. А потом я из программы в программу тиражирую свои "удачные" подходы к решению схожих задач, хотя может быть можно это делать более правильно. Ну вот теперь мне как раз-таки и хочется потихонечку начать "закрашивать" эти белые пятна.
0
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 79
15.05.2020, 20:06
Лучший ответ Сообщение было отмечено Power_Basic как решение

Решение

Цитата Сообщение от Power_Basic Посмотреть сообщение
01, 00, 00, 00, 02, 00, 00, 00, 03, 04, 05.
Такой результат просто получить через следующий код:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Option Explicit
 
Private Declare Sub CopyMemory Lib "kernel32" _
                    Alias "RtlMoveMemory" ( _
                    ByRef Destination As Any, _
                    ByRef Source As Any, _
                    ByVal Length As Long)
 
Private Type MyUDT
  A As Integer
  B As Long
End Type
 
Private Sub Command1_Click()
  Dim udt_MyUDT As MyUDT
  Dim arr_Byte_array(1 To 3)  As Byte
  Dim arr_Total_array()  As Byte
 
  udt_MyUDT.A = 1
  udt_MyUDT.B = 2
 
  arr_Byte_array(1) = 3
  arr_Byte_array(2) = 4
  arr_Byte_array(3) = 5
  
  ' // Выделяем память для структуры и массива
  ReDim arr_Total_array(LenB(udt_MyUDT) + UBound(arr_Byte_array) - 1)
  
  CopyMemory arr_Total_array(0), udt_MyUDT, LenB(udt_MyUDT)
  CopyMemory arr_Total_array(LenB(udt_MyUDT)), arr_Byte_array(1), UBound(arr_Byte_array)
  
  ' // Проверка
  Dim i As Long
  
  For i = LBound(arr_Total_array) To UBound(arr_Total_array)
    Debug.Print arr_Total_array(i); ", ";
  Next
  
End Sub
Цитата Сообщение от Power_Basic Посмотреть сообщение
01, 00, 02, 00, 00, 00, 03, 04, 05.
Для этого нужно либо вручную копировать каждое поле которое является невыровненным, либо использовать пайпы и стандартный механизм записи в файл (в этом случае легко можно записывать и большинство ссылочных типов, строки и т.п.). Это более гибкий режим и позволяет различные структуры сериализовать в байтовый массив (строки конвертируются в ANSI, как и при стандартной записи в файл, только никакого файла не создается:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
Option Explicit
 
Private Declare Function CreateNamedPipe Lib "kernel32" _
                         Alias "CreateNamedPipeA" ( _
                         ByVal lpName As String, _
                         ByVal dwOpenMode As Long, _
                         ByVal dwPipeMode As Long, _
                         ByVal nMaxInstances As Long, _
                         ByVal nOutBufferSize As Long, _
                         ByVal nInBufferSize As Long, _
                         ByVal nDefaultTimeOut As Long, _
                         ByRef lpSecurityAttributes As Any) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function PeekNamedPipe Lib "kernel32" ( _
                         ByVal hNamedPipe As Long, _
                         ByRef lpBuffer As Any, _
                         ByVal nBufferSize As Long, _
                         ByRef lpBytesRead As Long, _
                         ByRef lpTotalBytesAvail As Long, _
                         ByRef lpBytesLeftThisMessage As Long) As Long
Private Declare Function ReadFile Lib "kernel32" ( _
                         ByVal hFile As Long, _
                         ByRef lpBuffer As Any, _
                         ByVal nNumberOfBytesToRead As Long, _
                         ByRef lpNumberOfBytesRead As Long, _
                         ByRef lpOverlapped As Any) As Long
 
Private Type MyUDT
  A As Integer
  B As Long
End Type
 
Private Sub Form_Load()
    Dim hPipe       As OLE_HANDLE
    Dim iFN         As Integer
    Dim tUdt        As MyUDT
    Dim bArr(2)     As Byte
    Dim lTotalSize  As Long
    Dim bResult()   As Byte
    
    tUdt.A = 1
    tUdt.B = 2
    
    bArr(0) = 3
    bArr(1) = 4
    bArr(2) = 5
    
    hPipe = CreateNamedPipe("\\.\pipe\vbpipe", 3, 0, 255, -1, -1, 0, ByVal 0&)
    If hPipe = -1 Then Err.Raise 7
    
    iFN = FreeFile
    
    Open "\\.\pipe\vbpipe" For Binary As iFN
    ' // Сериализуем UDT
    Put 1, , tUdt
    ' // Добавляем массив
    Put 1, , bArr
    ' // Добавляем строку
    Put 1, , "hello!"
    
    Close 1
    
    If PeekNamedPipe(hPipe, ByVal 0&, 0, ByVal 0&, lTotalSize, 0) <> 0 Then
        If lTotalSize > 0 Then
            ReDim bResult(lTotalSize - 1)
            If ReadFile(hPipe, bResult(0), lTotalSize, 0, ByVal 0&) = 0 Then
                CloseHandle hPipe
                Err.Raise 7
            End If
        End If
    End If
    
    CloseHandle hPipe
 
 
  ' // Проверка
  Dim i As Long
  
  For i = LBound(bResult) To UBound(bResult)
    Debug.Print bResult(i); ", ";
  Next
 
End Sub
Добавлено через 1 минуту
А вообще тебе нужно использовать те функции что я написал и не заморачиваться с ручным размещением данных.
1
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
15.05.2020, 21:49  [ТС]
The trick, спасибо. Теперь я, по крайней мере, уже точно знаю, что "внутренними силами" Визуального Бейсика (без использования WINAPI-функций) такую операцию проделать невозможно.

Цитата Сообщение от The trick Посмотреть сообщение
А вообще тебе нужно использовать те функции что я написал и не заморачиваться с ручным размещением данных.
Да это да, это я уже уловил, так и буду действовать.
Но просто мне хотелось понять на будущее, есть ли какие-нибудь несложные способы, которые можно использовать для таких целей в схожих ситуациях.
0
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 79
15.05.2020, 22:22
Лучший ответ Сообщение было отмечено Power_Basic как решение

Решение

Цитата Сообщение от Power_Basic Посмотреть сообщение
The trick, спасибо. Теперь я, по крайней мере, уже точно знаю, что "внутренними силами" Визуального Бейсика (без использования WINAPI-функций) такую операцию проделать невозможно.
Есть еще LSet который позволяет кастовать разные структуры со скалярными типами, но у тебя динамический массив.
Т.е. можно иметь 2 структуры, одна из которых - просто массив фиксированной длины. Так вот в этот массив можно скопировать любую структуру стандартными средствами.

Цитата Сообщение от Power_Basic Посмотреть сообщение
Да это да, это я уже уловил, так и буду действовать.
Но просто мне хотелось понять на будущее, есть ли какие-нибудь несложные способы, которые можно использовать для таких целей в схожих ситуациях.
Несложный стандартный безопасный способ - это запись в файл, либо через LSet через промежуточный буфер если в памяти:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
Option Explicit
 
Private Type tA
    l As Long
    z As Double
End Type
 
Private Type tB
    q As Currency
    t As tA
    b As Byte
    j As Integer
End Type
 
Private Type tBuf
    bChunk(1024)    As Byte
End Type
 
Private Sub Form_Load()
    Dim t   As tB
    Dim b() As Byte
    
    t.b = 12
    t.q = 10@
    t.t.l = 1024
    t.t.z = 1.3
    t.j = 14
    
    b = SerializeB(t)
    
    Dim i As Long
    
    For i = 0 To UBound(b)
        Debug.Print b(i); ", ";
    Next
    
    
End Sub
 
Private Function SerializeB( _
                 t As tB) As Byte()
    Dim i   As Long
    Dim r() As Byte
    Static tBuf As tBuf
    
    LSet tBuf = t
    
    ReDim r(LenB(t) - 1)
    
    For i = 0 To LenB(t) - 1
        r(i) = tBuf.bChunk(i)
    Next
    
    SerializeB = r
    
End Function
1
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
16.05.2020, 18:21  [ТС]
Цитата Сообщение от The trick Посмотреть сообщение
Есть еще LSet который позволяет кастовать разные структуры со скалярными типами, но у тебя динамический массив.
Т.е. можно иметь 2 структуры, одна из которых - просто массив фиксированной длины. Так вот в этот массив можно скопировать любую структуру стандартными средствами.
На самом деле, LSet это очень интересное окно возможностей, про которое я не знал.

Цитата Сообщение от The trick Посмотреть сообщение
Несложный стандартный безопасный способ - это запись в файл
В смысле, записываем в файл в режиме BINARY всю нашу структуру, начиная с первого байта, а потом в том же режиме записываем весь наш исходный массив, начиная с байта, расположенного сразу после записанной структуры, а потом всё вместе считываем целиком в итоговый массив? Как говорится, дёшево и сердито
Не пробовал, но заранее уверен, что сработает безотказно. Буду иметь в виду такой подход на всякий случай. Особенно он будет хорош для небольших массивов.


Цитата Сообщение от The trick Посмотреть сообщение
либо через LSet через промежуточный буфер если в памяти:
Ну в идеале-то, да, конечно же, лучше бы, если всё в памяти делать.

Цитата Сообщение от The trick Посмотреть сообщение
либо через LSet через промежуточный буфер если в памяти:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
Option Explicit
 
Private Type tA
    l As Long
    z As Double
End Type
 
Private Type tB
    q As Currency
    t As tA
    b As Byte
    j As Integer
End Type
 
Private Type tBuf
    bChunk(1024)    As Byte
End Type
 
Private Sub Form_Load()
    Dim t   As tB
    Dim b() As Byte
    
    t.b = 12
    t.q = 10@
    t.t.l = 1024
    t.t.z = 1.3
    t.j = 14
    
    b = SerializeB(t)
    
    Dim i As Long
    
    For i = 0 To UBound(b)
        Debug.Print b(i); ", ";
    Next
    
    
End Sub
 
Private Function SerializeB( _
                 t As tB) As Byte()
    Dim i   As Long
    Dim r() As Byte
    Static tBuf As tBuf
    
    LSet tBuf = t
    
    ReDim r(LenB(t) - 1)
    
    For i = 0 To LenB(t) - 1
        r(i) = tBuf.bChunk(i)
    Next
    
    SerializeB = r
    
End Function
Ну это, как я понял, какой-то демонстрационный пример для перезаписи структуры со всевозможными типами данных её членов в массив байтов.
Хотелось бы всё-таки отталкиваться от моего стартового кода в топике ветки.
Ну например, меня тип данных Currency не интересует вообще никак.
Да и потом, здесь же мы по байтику весь массив перебираем:

Visual Basic
1
2
3
    For i = 0 To LenB(t) - 1
        r(i) = tBuf.bChunk(i)
    Next
Хотя, конечно, размер структуры обычно небольшой.

Ну а как потом массив-то присоединять?

Добавлено через 6 минут
Тоже с помощью цикла?
0
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 79
16.05.2020, 19:53
Цитата Сообщение от Power_Basic Посмотреть сообщение
В смысле, записываем в файл в режиме BINARY всю нашу структуру, начиная с первого байта, а потом в том же режиме записываем весь наш исходный массив, начиная с байта, расположенного сразу после записанной структуры, а потом всё вместе считываем целиком в итоговый массив? Как говорится, дёшево и сердито
Не пробовал, но заранее уверен, что сработает безотказно. Буду иметь в виду такой подход на всякий случай. Особенно он будет хорош для небольших массивов.
Да, ну это аналогично примеру что я привел с пайпами, но при использовании пайпов файла не создается, а все манипуляции проходят в памяти.

Цитата Сообщение от Power_Basic Посмотреть сообщение
Ну это, как я понял, какой-то демонстрационный пример для перезаписи структуры со всевозможными типами данных её членов в массив байтов.
Хотелось бы всё-таки отталкиваться от моего стартового кода в топике ветки.
Ну например, меня тип данных Currency не интересует вообще никак.
Да и потом, здесь же мы по байтику весь массив перебираем:
Да добавлять массив придется вручную в цикле - это единственный безопасный способ. Есть небезопасные способы, основанные на WINAPI.

Есть еще способ сериализации через COM-stream, но это еще сложнее, но более универсально.
0
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
16.05.2020, 21:21  [ТС]
Цитата Сообщение от The trick Посмотреть сообщение
Да, ну это аналогично примеру что я привел с пайпами, но при использовании пайпов файла не создается, а все манипуляции проходят в памяти.
Цитата Сообщение от The trick Посмотреть сообщение
Да добавлять массив придется вручную в цикле - это единственный безопасный способ. Есть небезопасные способы, основанные на WINAPI.
Есть еще способ сериализации через COM-stream, но это еще сложнее, но более универсально.
И следовательно мой предыдущий вывод остаётся в силе:

Цитата Сообщение от Power_Basic Посмотреть сообщение
Теперь я, по крайней мере, уже точно знаю, что "внутренними силами" Визуального Бейсика (без использования WINAPI-функций) такую операцию проделать невозможно.
И всё-таки у меня ещё теплется одна маленькая надежда
Вот например, Variant'ы можно как-нибудь приспособить для решения такой задачи?
Ну например, в первый Variant поместить всю нашу структуру, во второй наш массив, потом их каким-нибудь образом объединить в один общий Variant, ну а на последнем шаге извлечь из полученного Variant'а массив байтов?
Так не получится сделать?
0
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 79
16.05.2020, 21:52
Цитата Сообщение от Power_Basic Посмотреть сообщение
И следовательно мой предыдущий вывод остаётся в силе:
А как же вариант с файлом? Записали данные как нужно, потом прочитали в байтовый массив. Все решается только с помощью встроенных средств.

Цитата Сообщение от Power_Basic Посмотреть сообщение
Вот например, Variant'ы можно как-нибудь приспособить для решения такой задачи?
Нельзя. Иметь структуру переменного размера небезопасно и может привести к нарушению доступа к памяти при неправильном использовании, поэтому такую возможность намеренно запретили, также как и к примеру объединения.

Добавлено через 54 секунды
Цитата Сообщение от Power_Basic Посмотреть сообщение
И следовательно мой предыдущий вывод остаётся в силе:
А как же вариант с файлом? Записали данные как нужно, потом прочитали в байтовый массив. Все решается только с помощью встроенных средств.

Цитата Сообщение от Power_Basic Посмотреть сообщение
Вот например, Variant'ы можно как-нибудь приспособить для решения такой задачи?
Нельзя. Иметь структуру переменного размера небезопасно и может привести к нарушению доступа к памяти при неправильном использовании, поэтому такую возможность намеренно запретили, также как и к примеру объединения.
0
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
16.05.2020, 22:23  [ТС]
Цитата Сообщение от Power_Basic
И следовательно мой предыдущий вывод остаётся в силе:
Цитата Сообщение от The trick Посмотреть сообщение
А как же вариант с файлом? Записали данные как нужно, потом прочитали в байтовый массив. Все решается только с помощью встроенных средств.
Ну это да, я согласен, оптимальное решение.
Я имел в виду, что, не обращаясь к диску, не получится.

Цитата Сообщение от Power_Basic
Вот например, Variant'ы можно как-нибудь приспособить для решения такой задачи?
Цитата Сообщение от The trick Посмотреть сообщение
Нельзя. Иметь структуру переменного размера небезопасно и может привести к нарушению доступа к памяти при неправильном использовании, поэтому такую возможность намеренно запретили, также как и к примеру объединения.
Жаль. Это как раз тот самый "Саид", на которого я рассчитывал
Универсальный контейнер и всё такое.
0
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 79
16.05.2020, 23:05
Цитата Сообщение от Power_Basic Посмотреть сообщение
Я имел в виду, что, не обращаясь к диску, не получится.
Не обращаясь к диску только через LSet, но необходимо вручную копировать в цикле массив. Либо через небезопасные WINAPI аналоги как выше предлагалось. В VB6 можно только скопировать динамический массив целиком встроенными средствами, невозможно создать универсальную функцию (в рамках концепции и синтаксиса VB6) которая будет копировать массивы частями, поэтому такой возможности нет. Можно создать только пользовательскую функцию которая будет копировать определенный тип массива.

Добавлено через 12 минут
Цитата Сообщение от Power_Basic Посмотреть сообщение
Жаль. Это как раз тот самый "Саид", на которого я рассчитывал
Универсальный контейнер и всё такое.
Variant позволяет хранить определенный набор типов данных. Хранение структур динамического размера вероятно невозможно не только в VB6, но и в COM вообще. Постоянного - пожалуйста.
В COM обычно если нужно сохранить состояние объекта (к примеру свойства контролов и т.п.) используется IPersist интерфейс (в VB6 аналог PropertyBag), туда записывается состояние которое безопасно может быть передано куда-нибудь, а затем прочитано.
С точки зрения безопасного программирования, не нужно иметь структуру MyUDT, а нужно иметь класс, в котором будет свойство - Buffer, которое будет хранить данные. При сериализации каждое поле необходимо сохранять в том порядке в котором оно ожидается в бинарном представлении. Все это реализуемо в рамках как безопасного программирования, так и небезопасного. Полагаться на то как данные структуры размещаются в пяти - не нужно, вообще нужно держать в уме тот факт что о размещении в памяти вообще не нужно думать поскольку это машинозависимая вещь. Это в рамках безопасного программирования. Поэтому каждое поле необходимо сериализовать отдельно в нужном формате.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
16.05.2020, 23:05
Помогаю со студенческими работами здесь

Создать структуру для работы с массивом
пробую написать программу с использованием структуры.. Создать структуру для работы с массивом. Данные структуры: массив N(10)....

Как создать структуру-список, поля которой — ссылка на такую же структуру
Суть вопроса в том, как создать структуру-список, поля которой - ссылка на сл. элемент(такую же структуру) и ссылка на объект, относящийся...

Как создать структуру, где будут поля с указателями на эту же структуру?
#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; typedef struct DoubleQueue { queue* ar; queue* al; int data; }...

Как правильно написать функцию, которая редактирует структуру по полю Name и возвращает новую, исправленную структуру?..
Нужно отредактировать структуру по выбору пользователя. Проблема заключается в создании функции. Подскажите, а лучше покажите, как...

как грамотно форматировать?
подскажите как грамотно форматировать данный код? &lt;div class=&quot;penci_post_content&quot;&gt;&lt;h3 class=&quot;penci__post-title...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru