Массив указателей

Clarion, Clarion 7

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7372
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

Массив указателей

Сообщение Игорь Столяров »

Что-то не то в консерватории … :( Делаем:

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

grq  Group, dim(20)
q    &Queue.

  Map
    LoadMyQueue(*Queue)
  end

   Code
   ...
   If ~(grq[1].q &= Null)
       LoadMyQueue(grq[1].q)  ! ОШИБКА ТРАНСЛЯЦИИ - НЕВЕРНЫЙ ТИП ПАРАМЕТРА 
   end
Можно попробовать обмануть судьбу:

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

grq  Group, dim(20)
q    &Queue.

QTMP &Queue

  Map
    LoadMyQueue(*Queue)
  end

   Code
   ...
   If ~(grq[1].q &= Null)
       QTMP &= grq[1].q  
       LoadMyQueue(QTMP)  ! ТРАНСЛЯЦИИ - OK !
   end
И всё с треском вываливается на выполнении при первом обращении к QUEUE ! :(
За теми кто отстал - не возвращаться. (С) Кодекс
PavelNK
Старожил
Сообщения: 262
Зарегистрирован: 15 Март 2011, 8:02

Массив указателей

Сообщение PavelNK »

grq group, dim(20),pre(gr)
q &Queue
end

vq &queue

rq queue
num long
end

Map
LoadMyQueue(*Queue)
end


CODE

rq.num = 1
add(rq)

gr:q[1] &= rq

If ~(grq[1].q &= Null)
vq &= grq[1].q
LoadMyQueue(vq) ! ОШИБКА ТРАНСЛЯЦИИ - НЕВЕРНЫЙ ТИП ПАРАМЕТРА
end

return
Аватара пользователя
vic7tar
Ветеран
Сообщения: 365
Зарегистрирован: 09 Февраль 2017, 20:12

Массив указателей

Сообщение vic7tar »

Да вроде бы всё нормально:

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

   Program

   Map
     LoadMyQueue(*Queue)
   end

grq  Group, pre(grq), dim(20)
q    &Queue.

Q1   Queue
a    long
b    long.

QTMP &Queue

   Code
   
   Q1.a = 666 
   Q1.b = 777 
   add(Q1)
   grq:q[1] &= Q1
   
   If ~(grq[1].q &= Null)
       QTMP &= grq:q[1]  
       LoadMyQueue(QTMP)  ! ТРАНСЛЯЦИИ - OK !
   end

   
LoadMyQueue Procedure(*Queue mq)

   code 
   message( what(mq, 1) )
   message( what(mq, 2) )
C10, Win10x64
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3133
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 10 раз
Поблагодарили: 28 раз
Контактная информация:

Массив указателей

Сообщение Дед Пахом »

PavelNK, не надо постить код сплошным текстом.
С уважением, ДП
PavelNK
Старожил
Сообщения: 262
Зарегистрирован: 15 Март 2011, 8:02

Массив указателей

Сообщение PavelNK »

Дед Пахом писал(а): 26 Июль 2019, 22:22PavelNK, не надо постить код сплошным текстом.
Пардон, очень торопился
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7372
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

Массив указателей

Сообщение Игорь Столяров »

Таки интересно было бы понять, почему указатель на QUEUE "портится", если он в массиве группы. т.е.

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

grq  Group
q    &Queue.  ! Вот так - это обычный указатель на QUEUE

grq  Group, dim(20)
q    &Queue.  ! А вот так - это тоже указатель, но ХЗ на что ... :(
Что-то тут нечисто ... :(
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
vic7tar
Ветеран
Сообщения: 365
Зарегистрирован: 09 Февраль 2017, 20:12

Массив указателей

Сообщение vic7tar »

Что означает "портится"?
C10, Win10x64
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7372
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

Массив указателей

Сообщение Игорь Столяров »

vic7tar писал(а): 27 Июль 2019, 10:20Что означает "портится"?
Я ранее приводил пример, повторюсь:

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

grq  Group, dim(20)
q    &Queue.

  Map
    LoadMyQueue(*Queue)
  end

   Code
   ...
   If ~(grq[1].q &= Null)
       LoadMyQueue(grq[1].q)  ! ОШИБКА ТРАНСЛЯЦИИ - НЕВЕРНЫЙ ТИП ПАРАМЕТРА 
   end
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
vic7tar
Ветеран
Сообщения: 365
Зарегистрирован: 09 Февраль 2017, 20:12

Массив указателей

Сообщение vic7tar »

Игорь Столяров писал(а): 27 Июль 2019, 10:32LoadMyQueue(grq[1].q) ! ОШИБКА ТРАНСЛЯЦИИ - НЕВЕРНЫЙ ТИП ПАРАМЕТРА
grq[1].q - это первый элемент в массиве групп со своим адресом, а вот уже по этому адресу и находится ссылка на очередь. Ошибка при трансляции правильная.
C10, Win10x64
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7372
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

Массив указателей

Сообщение Игорь Столяров »

vic7tar писал(а): 27 Июль 2019, 11:27а вот уже по этому адресу и находится ссылка на очередь
Так, тут уже что-то больше моего понимания … :) Потому, что без массива - всё работает штатно.
Подскажите пожалуйста, а как тогда правильно передать очередь из этого массива групп в процедуру ?

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

  LoadMyQueue(grq[1].q)
Заменяем на

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

  LoadMyQueue(Address(grq[1].q))
?
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
vic7tar
Ветеран
Сообщения: 365
Зарегистрирован: 09 Февраль 2017, 20:12

Массив указателей

Сообщение vic7tar »

В моём примерчике это делается через промежуточную ссылку QTMP (QTMP &Queue).
Address(grq[1].q) - это как раз и будет адрес элемента в массиве групп.

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

   a# = address( grq[1].q )      ! адрес в массиве
   peek(address(grq[1].q), b#)   ! b# - адрес ссылки на очередь
C10, Win10x64
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7372
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

Массив указателей

Сообщение Игорь Столяров »

vic7tar писал(а): 27 Июль 2019, 12:02В моём примерчике это делается через промежуточную ссылку QTMP (QTMP &Queue).
Спасибо - со второго раза понял ! :) Буду пробовать ...
За теми кто отстал - не возвращаться. (С) Кодекс
Yufil
Ветеран движения
Сообщения: 1277
Зарегистрирован: 16 Май 2006, 14:34
Контактная информация:

Массив указателей

Сообщение Yufil »

Игорь Столяров писал(а): 26 Июль 2019, 8:19
RaFaeL писал(а): 26 Июль 2019, 7:34Очередь указателей чем не подходит?
Я думал в эту сторону - не очень удобно. Во первых для передачи параметров внутри группы - это снова делать
указатель на типизированную очередь указателей (QUEUE внутри GROUP не может быть).
Во-вторых добавлять записи, считывать записи … :(
Но если современная наука ничего другого не предложит - то видимо придётся делать через QUEUE указателей.
Всё-таки это самое то, зачем мудрить ...
Из описанного выше класса DumpClass

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

DumpQ     Queue,Type
Id        Cstring(20)  ! Идентификатор переменной
Type      String(1)    ! Тип поля
Addr      Any          ! Адрес поля
AddrG     &Group       ! Адрес группы
AddrQ     &Queue       ! Адрес очереди
Address   Ulong        ! Истинный адрес группы
RecSize   Long         ! Размер поля
RecCount  Long         ! Количество записей
          End


DumpClass Class,Type,Module('Dumper.Clw')
Q         &DumpQ
DebugInfo Cstring(1000)
Construct  Procedure
Destruct  Procedure
AddField  Procedure(String,*?)
AddField  Procedure(String,*Group)
AddField  Procedure(String,*Queue)
SaveBlob  Procedure(*Blob)
LoadBlob  Procedure(*Blob),Long,Proc
          End

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

DumpClass.Construct  Procedure
                     Code
                     Self.Q &= New DumpQ
                     Clear(Self.Q)
                     Return

DumpClass.AddField   Procedure(String Id,*Queue Field)
                     Code
                     Clear(Self.Q)
                     Self.Q.Id=Clip(Upper(Id))
                     Get(Self.Q,+Self.Q.Id)
                     If ErrorCode()
                       Add(Self.Q,+Self.Q.Id)
                     End
                     Self.Q.Type=Type:Queue ! Varia
                     !Self.Q.Addr  &= Field
                     Self.Q.AddrQ &= Field
                     Self.Q.Address=Address(Self.Q.AddrQ)
                     Self.Q.RecSize= Len(Field & '')
                     Put(Self.Q)
                     Return

DumpClass.SaveBlob   Procedure(*Blob BlobField)
Loc:Size             Long  ! Размер
Loc:DumpQ            Long  ! Счётчик записей в дампе
Loc:RecNo            Long  ! Количество записей в списке
Loc:SavePtr          Long  ! Сохранение указателя
Loc:Pos              Long
.... 

                     Loop Loc:DumpQ=1 to Records(Self.Q)
                       Get(Self.Q,Loc:DumpQ)
                        ...
                       Case Self.Q.Type
                       ...
                       Of Type:Queue
                         !  Перекинем очередь в Blob 
                         If Records(Self.Q.AddrQ)
                           |Self.DebugInfo=Self.DebugInfo & '<13,10> Очередь ' & Self.Q.Id & '/' &Records(Self.Q.AddrQ)
                           Rh:RecCount=Records(Self.Q.AddrQ)
                           BlobField[Loc:Pos : Loc:Pos+Size(RH)-1] = RH
                           Loc:Pos+=Size(RH)
                           Loc:SavePtr=Pointer(Self.Q.AddrQ)
                           Loop Loc:RecNo=1 to Records(Self.Q.AddrQ)
                             Get(SelF.Q.AddrQ,Loc:RecNo)
                             CopyMemory(Address(Temp),Self.Q.Address,Self.Q.RecSize)
                             BlobField[Loc:Pos : Loc:Pos+Self.Q.RecSize-1] = Temp
                             Loc:Pos+=Self.Q.RecSize
                           End
                         End

Вполне удобно и комфортно для работы с абстрактными очередями, очередь хранится вместе с необходимыми реквизитами
Ответить