SAFEARRAY Tricks

Разговоры на любые темы: вы можете обсудить здесь какой-либо сайт, найти единомышленников или просто пообщаться...
GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 22.04.2004 (Чт) 9:11

Я даже не понял, какой цели ты хотел достигнуть... В любом случае, ты определил массивы фиксированного размера, мы их вообще не рассматривали :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Fedorfx
Постоялец
Постоялец
 
Сообщения: 371
Зарегистрирован: 10.10.2002 (Чт) 0:14

Сообщение Fedorfx » 22.04.2004 (Чт) 18:32

Есть несколько различных классов
Один - хранилище данных
Остальные - обработчики этих данных
Цель - получить доступ к данным класса для последующей обработки с наименьшими потерями времени. ( сейчас использую такой метод
Arr1=Arr2) Arr1 -массив переменной длинны.
Думаю сделать так
Создать в классах обработчиках массивы и перенаправить адреса на адрес главного массива.
Трудности -
При удалении класса обработчика некорректно удаляется ссылка на массив.
Код: Выделить всё
  Dim Adr as long
  Dim r1(1 To 10) as long
  Dim r2(1 To 1) as long

  r1(1) = 33
  GetMem4 ArrPtr(r1), ArrPtr(r2)
' До сих пор все ок
' Пытаюсь удалить массив r1
  GetMem4 r2, VarPtr(Adr)
  SafeArrayDestroyDescriptor ByVal Adr
' Вот после этой строчки глюки ( массив становится интом
  PutMem4 12, 0

А если удаляю Erase R2 то первый массив удаляется корректно а второй с ошибкой.

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

Сообщение GSerg » 23.04.2004 (Пт) 9:12

1. Все массивы сделать динамическими.
2. Хранилище данных должно создаваться раньше обработчиков, инициализация его массива встроенными средствами VB.
3. Обработчик содержит пустой динамический массив.
4. При создании обработчика вызывать CreateSAFEARRAY, указывая в качестве источника данных VarPtr первого элемента массива хранилища.
5. Обработчики должны уничтожаться раньше хранилища. При этом вызывается DestroySAFEARRAY.
6. Последним уничтожается хранилище. Никаких tricks, VB всё сделает сам.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Fedorfx
Постоялец
Постоялец
 
Сообщения: 371
Зарегистрирован: 10.10.2002 (Чт) 0:14

Сообщение Fedorfx » 26.04.2004 (Пн) 23:34

Тут вот какой замут
Хочется в классе 1 сделать массив с данными
Сделать в классе 2 указатель на массив и направить его на 1й массив
дальше работать с классом 2
если произойдут изменения с массивом 1 ( данные или размер) то указатель во втором классе все это отобразит

В том примере что вы предлагаете мне необходимо перед каждым проходом копировать структуру массива в указатель заново, иначе я не могу узнать был ли массив изменен в размере, а это издержки.
Вот я и подумал а что если я сделаю так.
Код: Выделить всё
GetMem4 ArrPtr(r1), ArrPtr(r2)

И это класно работает. Я имею массив в многих местах одновременно.
и тогда мне не надо каждый раз обновлять указатель.
Но тут бяка - как порвать этот порочный круг, при убийстве любого из массивов второй на какое то время указывает на несуществующий участок памяти, и прога вместе в VB летит в тартарары

Есть у кого какие мысли по этому поводу??

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

Сообщение GSerg » 27.04.2004 (Вт) 8:28

Ну тогда любой массив, созданный через GetMem4, нужно убивать через PutMem4 arrptr(r2), 0.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Fedorfx
Постоялец
Постоялец
 
Сообщения: 371
Зарегистрирован: 10.10.2002 (Чт) 0:14

Сообщение Fedorfx » 27.04.2004 (Вт) 10:11

Я тоже до этого допер, только уже засыпал, и лень вставвать было.
P.S. Хочу сказать большое спасибо за столь познавательные и полезные топики ( сейчас вникаю в АСМ.Кстати есть ли там какие либо мысли по передаче аргументов из реалтайма. Примерчик бы :-) )

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

Сообщение GSerg » 27.04.2004 (Вт) 10:18

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

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

Сообщение alibek » 27.04.2004 (Вт) 10:45

Винда не является операционной системой реал-тайм, так что строить на ее основе реал-тайм подсистемы не совсем правильно.
Lasciate ogni speranza, voi ch'entrate.

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

Сообщение GSerg » 27.04.2004 (Вт) 10:47

Правильно! :) (только я ни черта не понял)
Только там (как я наконец-то посмотрел) речь шла об использовании в асм-коде переменных VB :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

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

Сообщение GSerg » 08.05.2004 (Сб) 8:19

Всё-таки пробивать стены головой возможно :twisted:
Вот как можно получить (SAFEARRAY**) стрингового массива:

Код: Выделить всё
Public Function StrArrPtr(arr() As String, Optional ByVal IgnoreMe As Long = 0) As Long
  GetMem4 VarPtr(IgnoreMe) - 4, VarPtr(StrArrPtr)
End Function

Второй параметр игнорим. Всегда и везде.


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

TEH3OP
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 143
Зарегистрирован: 12.12.2003 (Пт) 20:19
Откуда: Москва

Насчёт получения адреса структуры SAFEARRAY.

Сообщение TEH3OP » 17.05.2004 (Пн) 15:05

Ежели он -- адрес постоянный, то его мона просто получить, выковырив из Variant'а. Для этого надо присвоить какой-нить Variant переменной, созданный массив и скопировать оный Variant на такую чтучку:
Код: Выделить всё
Public Type VariantInfo
    vt As Integer
    wReserved1 As Integer
    wReserved2 As Integer
    wReserved3 As Integer
    LoUnion As Long
    HiUnion As Long
End Type


В LoUnion буит ссылка на SAFEARRAY.

Спасибо за внимание...

PS: Копировать так:
Код: Выделить всё
CopyMemory <имя пременной типа VariantInfo>, <имя переменной типа Variant>, 16&

Пред.

Вернуться в Народный треп

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

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

    TopList