SAFEARRAY, FileMapping и Variant Array

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

SAFEARRAY, FileMapping и Variant Array

Сообщение Avtopic » 11.05.2007 (Пт) 13:11

Здравствуйте!

1. один из этих трех массивов
Код: Выделить всё
Arr(0 To 2, 0 To N, 0 To M) As Variant
Arr(0 To N, 0 To 2, 0 To M) As Variant
Arr(0 To N, 0 To M, 0 To 2) As Variant

Можно или нет представить себе как двухмерный массив, с тремя Page-ми,
т.е. три двухмерных массива расположенный в области памяти один за другим, если да, какой, и нет ли где ни будь готового указателя на эти Pages.

2. Как я понимаю размер двухмерного Variant массива в VB состоит:
4-байта для указателя
8-байта для размера элемента
4-адрес данных (дальше pData)
8-первая размерность
8-Втарая размерность
В самой области, куда указывает pData, для каждого элемента по 16-байт.



Если все правильно, то объясните следующее:
В качестве pData передаю адрес проецируемого Mapping File-а
Как может помещаться Arr(0 To 9, 0 To 24) As Variant массив в файл
у которого dwMaximumSizeLow=1
и как не может помещаться Arr(0 To 9, 0 To 25) As Variant массив в файл
у которого dwMaximumSizeLow=4096 и опять же как может помещатся в dwMaximumSizeLow=4096 + 1
тогда как я подсчитываю для первого массива нужен как минимум
10Х25Х16=4000 байт
а для второго 10Х26Х16=4160 байт

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

Сообщение Viper » 11.05.2007 (Пт) 13:44

вот ведь... Все тебе нужное есть в кирпичах тут, тут и здесь. Также стоит глянуть статью GSerg вот здесь вот
Последний раз редактировалось Viper 11.05.2007 (Пт) 14:43, всего редактировалось 1 раз.
Весь мир матрица, а мы в нем потоки байтов!

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 11.05.2007 (Пт) 14:16

Первым делом, спасибо!
Все четыре и их содержание почти наизусть знаю, и вообще, если что понимаю в этом, тоже оттуда, и в проекте один модуль ваш другой GSerg-а.
но там (по ссылкам, и не только там) не смог найти ответ на эти вопроси.
только один раз помню, встречал, кто-то кого-то благодарил, что ему объяснили про первые 4000 баит если dwMaximumSizeLow=1 и то не смог найти.
Да, раз уж упомянули эти ссылки, еще всегда хотел спросит но не знал где разместить вопрос, нигде не смог найти что из себя представляет "переобъявление" и как это работает
переобъявляем функцию VarPtr под именем ArrPtr:
Declare Function ArrPtr Lib "msvbvm60" Alias "VarPtr" (arr() As Any) As Long

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

Сообщение Viper » 11.05.2007 (Пт) 14:46

Э... а в чем проблема то с "переобъявлением"? Такое объявление VarPtr позволяет получить адрес структуры SAFEARRAY для массива.
Весь мир матрица, а мы в нем потоки байтов!

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

Сообщение tyomitch » 11.05.2007 (Пт) 15:08

Явный ответ на первый вопрос: первый индекс меняется быстрее всего, последний медленнее всего. Три страницы будет в последнем варианте.
Изображение

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

Сообщение Viper » 11.05.2007 (Пт) 15:23

по второму вопросу:

4 байта указатель на SAFEARRAY
16 байт структура +8 байт на каждую размерность SAFEARRAY
16 байт минимум на каждый элемент VARIANT (для строк, UDT и объектов размер бужет еще больше)

По поводу собстно вопроса помещения/непомещения в проекцию массива Variant, а что у тебя в Variant и как ты это помещаещь в проекцию?
Весь мир матрица, а мы в нем потоки байтов!

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 11.05.2007 (Пт) 15:43

"переобъявлением" никаких проблем, интересует сущность

Повторяю все что написано в лынках работает и в маем проекте, причем очень хорошо.
в первом варианте, меня интересует не созданный описанным в лынках способом массивы, а обвяленные Dim, и являются ли они непрерывным адресным пространством, начиная с pData, и располагаются или нет по page-но один за другим

Во втором вопросе меня интересует размер mapping файла, который нужно выделить чтобы там поместился определенный двумерный массив, мой расчет не совпадает с реально требующим (примеры выше).

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 11.05.2007 (Пт) 15:45

пока писал ответ, пропустил два ответа.
в Variant массиве у меня Long, Double, строки.

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

Сообщение tyomitch » 11.05.2007 (Пт) 15:46

1) Да, являются непрерывным.
2) Как ты определяешь, поместился массив или нет?
Изображение

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 11.05.2007 (Пт) 17:26

Я уже думал что мою подсет запретили, еле зашел на форум. :)

tyomitch писал(а):2) Как ты определяешь, поместился массив или нет?
например при dwMaximumSizeLow=4096
Arr(9, 25) = “чему-то” сбивается. (вылетает программа)
при dwMaximumSizeLow=4097
Arr(9, 25) = “чему-то” работает.

а на что сбивается, нахожу методом последовательного приближения. :)

...но почему спросили? тут наверно что-то кроется.


Нужный размер всегда крутится вокруг да около
(1-вая размерность + 1) * (2-вая размерность + 1) * 16 – 4096
(проверял для всяких размерностей, от 1Х1 до 100000Х40).

В принципе, почему “– 4096” как то могу понять, наверно первые 4096 выделяются обязательным образом, если dwMaximumSizeLow>0 и это “смещение” постоянно присутствует,
и (1-вая размерность + 1) * (2-вая размерность + 1) * 16 понимаю, но почему завысимость непостоянна, не смог понять. Для проверенных вариантов (размерностей от 1Х1 до 100000Х40) ошибка в вычислении меняется от - 48 до плюс 2086 байт.

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

Сообщение tyomitch » 11.05.2007 (Пт) 18:18

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

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 13.05.2007 (Вс) 14:34

как писал, адрес mapping области устанавливаю как адрес данных Variant массива.
В другом процессе, все открывается, и массив (в качестве адреса данных та же область), работает также исправна, как массив в первом процессе.
Все корректно, если Variant данные помещаются в 16 байт, т.е. пока там данные, а не указатели. Как только там оказываются указатели, (доп. часть данных содержит строку) программа грохается.
Причина наверно ясна, в первом процессе мы подменили адрес данных на mapping область, но в Variant элементах совсем не обязательно, что адрес, куда они будут указывать, тоже попадут в этот mapping и sharing область. Как результат, второй процесс жалуется на error 14 Out Of space, это в лучшем случае, в худшем, просто падает.
Из этого положения есть выход?

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

Сообщение tyomitch » 13.05.2007 (Вс) 14:56

Есть. Перестать изобретать велосипед с квадратными колёсами, и сделать ActiveX EXE.
Изображение

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 13.05.2007 (Вс) 15:25

tyomitch

Один процесс, получает данные в Variant массив, много данных, одновременно.
Этот же процесс, после приема, должен выставить эти данные на общее пользование, для двух или трех других процессов. Очень желательно не на диск.
Это можно сделать на ActiveX еxe с круглимы колесами?

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

Сообщение tyomitch » 13.05.2007 (Вс) 15:29

Можно. Причём безо всяких API. И работать, на самом деле, будет через такую же шаренную память; только тебе не нужно будет об этом заботиться самому.
Изображение

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 18.05.2007 (Пт) 13:50

Ваш ответ, спровоцировал меня, наконец-то разобраться в COM технологии. После него не написал ни одной строчки кода, только читаю.
Из всего прочитанного вынес заключение, что мне нужен, действительно, ActiveX EXE, Спасибо!

Допустим, имею Процесс - A и Процесс - C
Для простейшего эксперимента сделал ActiveX EXE, назовем “B”?
открыл в нем модуль и только одну строчку Public MyArre as Variant
и класс для работы с массивом MyArre.
В Процессе C заполняю массив в B а в Процессе A читаю. Чудесааа! видит!

tyomitch, я правильно понял наставления или опять не в ту сторону пру?
если все правильно, тогда имею такой вопрос,
в Процессе C массив С передаю в класс в В и тот заполняет MyArre.
в Процессе А массив А обращается к классу в В и тот заполняет массив А.

Что находится в А? указатель на MyArre, указатель на массив С, или сами данные?

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

Сообщение tyomitch » 18.05.2007 (Пт) 14:23

Я не понимаю, что значит "массив обращается к классу".
Изображение

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 18.05.2007 (Пт) 15:08

плохо написал, вызывается функция
Код: Выделить всё
Public Function getArray() As Variant
    getArray = MyArre
End Function
(Property get, просто для примера выбрал функцию)

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

Сообщение tyomitch » 18.05.2007 (Пт) 15:51

Такое присваивание копирует данные массива.
Изображение


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

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

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

    TopList