Корректная работа с указателями ?

Clarion, Clarion 7

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

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

Корректная работа с указателями ?

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

Привет всем !

Сразу хочу сказать, что в справке ответа не нашел, а тесты работают неадекватно,
поэтому хочу спросить. Вопрос: можно ли работать с указателем как параметром
до инициализации переменной ?

Элементарный пример:

Map
OneProc
TwoProc(*cString)
end

OneProc Procedeure
MyString &cString
Code
TwoProc(MyString)
Message(MyString)
Dispose(MyString)

TwoProc Procedure(MyNewString)
Code
MyNewString = New(cString(255))
MyNewString = 'Привет ! Это новая строка ...'

Такая работа корректна ? Или в этом случае надо делать как-то по другому ?
Заранее спасибо за любой ответ .... :)
Make Clarion Great Again ! 😎
Аватара пользователя
StillZero
Ветеран
Сообщения: 458
Зарегистрирован: 06 Июль 2005, 2:17
Откуда: Хабаровск
Поблагодарили: 1 раз
Контактная информация:

Re: Корректная работа с указателями ?

Сообщение StillZero »

да собственно, почему нет
можно вообщем и уничтожать внутри процедуры и по новой создавать и по другому всякому можно
на NULL тока желательно проверять, ну и уничтожать соотвественно
а случаем не лисапед для DynStr.inc?
по аэродрому...
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8033
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 96 раз

Re: Корректная работа с указателями ?

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

Нет. В данном случае пытаюсь организовать работу с почтой (отправка e-mail).
Дело в том, что размер почтового сообщения можно определить только после его
создания. Поэтому процедура TwoProc должна сама создать строку с сообщением
нужного ей размера и вернуть ее в процедуру OneProc для дальнейшей обраьотки
(отправки по SMTP). Просто как-то неоднозначно определен статус указателя до
иницализации самой переменной. Понятно, что использовать переменную до инициализации
нельзя, а вот можно ли оперировать самим указателем ... непонятно .... :(
Make Clarion Great Again ! 😎
Аватара пользователя
WadimZapara
Активист
Сообщения: 181
Зарегистрирован: 11 Июнь 2008, 12:11
Откуда: Тамбов

Re: Корректная работа с указателями ?

Сообщение WadimZapara »

А чем не нравится так:

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

   PROGRAM
    MAP
SingleProc    Function(...),*CString
    END
c  &CString
  CODE
  c &= SingleProc(...)
! обработка
 Dispose(c)
!End of Program

SingleProc    Function(...)
cStr   &CString
N       LONG
   Code
! вычисление длины N
   cStr &= NEW(CString(N))
! обработка...
 RETURN cStr
Компьютер имеет то преимущество перед мозгом, что им пользуются...
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8033
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 96 раз

Re: Корректная работа с указателями ?

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

Абсолютно нравится и все хорошо .... до тех пор пока функция возвращает текстовую строку.
А если результат - бинарные данные (в т.ч. и с кодом 00h), этот пример перестает работать по понятным причинам .... :(
Make Clarion Great Again ! 😎
Аватара пользователя
StillZero
Ветеран
Сообщения: 458
Зарегистрирован: 06 Июль 2005, 2:17
Откуда: Хабаровск
Поблагодарили: 1 раз
Контактная информация:

Re: Корректная работа с указателями ?

Сообщение StillZero »

я не понял проблемы, ну используй memcpy, вроде кто то говорил уже
по аэродрому...
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8033
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 96 раз

Re: Корректная работа с указателями ?

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

Не умею я использовать memcpy ...
А можно какой-нибудь элементарный пример, что бы было видно идею ... ?
Как, например в предыдущем примере. Заранее спасибо !
Make Clarion Great Again ! 😎
Аватара пользователя
StillZero
Ветеран
Сообщения: 458
Зарегистрирован: 06 Июль 2005, 2:17
Откуда: Хабаровск
Поблагодарили: 1 раз
Контактная информация:

Re: Корректная работа с указателями ?

Сообщение StillZero »

Описываешь прототип

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

 MAP ! можно в inside the global map, тогда MAP END не надо
 MODULE('WinApi')
 my_memcpy(LONG addrTarget,LONG addrSource,LONG inSize),LONG,RAW,NAME('_memcpy'),PROC
!                куда              откуда       размер
 END
 END
типо такого, но надо знать адрес где лежат данные и их длину, я так понял
это у тебя есть, твой LPVOID это не *CSTRING, а обычный LONG, и в эту переменную
тебе положат адрес данных

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

CopyBufToString PROCEDURE(LONG inLen, LONG inAddr)
loc:Buf                 &STRING
 CODE
 loc:Buf &= NEW STRING(inLen) 
 my_memcpy(ADDRESS(loc:Buf),inAddr,inLen)

 RETURN loc:Buf
по аэродрому...
Аватара пользователя
WadimZapara
Активист
Сообщения: 181
Зарегистрирован: 11 Июнь 2008, 12:11
Откуда: Тамбов

Re: Корректная работа с указателями ?

Сообщение WadimZapara »

у меня есть работающая функция. может в ней дополнительно идею подсмотришь:

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

  MAP
      Module ('kernel32.dll')
         ! Unicode CString --> CString
         WideCharToMultiByte(Unsigned CodePage, ULong dwFlags,                |
                             *CString lpWideCharStr,  Signed cchWideChar=-1,  |
                             *CString lpMultiByteStr, Signed cbMultiByte,     |
                             ULong Addr_lpCStr_DefaultChar=0, ULong lpBool_UsedDefaultChar=0), Signed, RAW, Pascal, Dll, Name('WideCharToMultiByte')
         ! CString --> Unicode CString
         MultiByteToWideChar(Unsigned CodePage, ULong dwFlags,                |
                             *CString lpMultiByteStr, Signed cbMultiByte,     |
                             *CString lpWideCharStr,  Signed cchWideChar), Signed, RAW, Pascal, Dll, Name('MultiByteToWideChar')

      End

       GetValFromAddr(String Type_WCS124L6R8, ULong addr, Long Leng=-1), ?, Name('GetValFromAddr@ZWM_Function')
       WideCStr_To_Str(*CString cstr, Long Leng=-1), String, Name('WideCStr_To_Str@ZWM_Function')
       Str_To_WideStr (String str), String, Name('Str_To_WideStr@ZWM_Function')
  END

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

!==========================================================================================
GetValFromAddr       FUNCTION (String Type_WCS124L6R8, ULong addr, Long Leng=-1) !, ?
!==========================================================================================
! Реализует возврат значения по указателю.
! На входе: addr    - адрес значения
!           Type_?  - литера 'C' или 'c'         - вернуть String, то есть в ADDR адрес CString
!                     литера 'W' или 'w'         - вернуть String, полагая в ADDR адрес WideString (Unicode),
!                                                  при этом может быть задан параметр Leng > 0 число символов (а не байт)
!                     литера 'S' или 's'         - вернуть String, то есть в ADDR адрес String, при этом обязателен
!                                                  параметр Leng > 0, число байт
!                     литера '1'                 - вернуть Byte,    то есть в ADDR адрес байта
!                     литера '2'                 - вернуть USort,   то есть в ADDR адрес 2-байтового числа
!                     литера 'L' или 'l' или '4' - вернуть Long,    то есть в ADDR адрес 4-байтового числа
!                     литера '6'                 - вернуть строку из 6 байт
!                     литера 'R' или 'r' или '8' - вернуть REAL
! Следующие структуры используют одно и то же место в памяти
! и реализуют получение по адресу значения

AddressX  Group                 ! адрес на значение переменной
addrX       ULong
lng         ULong
          End
pCString  Group,Over(AddressX)    ! ссылка на CSTRING
_str        &CString
          End
p_String  Group,Over(AddressX)    ! ссылка на STRING
_str        &String
          End
pLong     Group,Over(AddressX)    ! ссылка на ULong
_long       &ULong
          End
pByte     Group,Over(AddressX)    ! ссылка на Byte
_byte       &Byte
          End
pUShort   Group,Over(AddressX)    ! ссылка на UShort
_short      &UShort
          End
pReal     Group,Over(AddressX)    ! ссылка на Real
_real       &Real
          End

  CODE
  
  AddressX.addrX = addr
  Case Upper(Type_WCS124L6R8)
    Of 'C'
      Return(pCString._str)
    Of 'W'
      Return( WideCStr_To_Str(pCString._str, Leng) )
    Of 'S'
      If Leng < 1 Then Return ('').
      AddressX.lng = Leng
      Return(p_String._str)
    Of '1'
      Return(pByte._byte)
    Of '2'
      Return(pUShort._short)
    Of '4' OrOf 'L'
      Return(pLong._long)
    Of '6'
      AddressX.lng = 6
      Return(p_String._str)
    Of '8' OrOf 'R'
      Return(pReal._real)
    Else
      IF MESSAGE('Непоправимая ошибка программиста.|'& |
                 'Нужно задавать тип источника как один из:|'& |
                 '  "C" или "c"         - CSTRING|'& |
                 '  "W" или "w"         - Unicode CSTRING или Unicode STRING|'& |
                 '  "S" или "s"         - STRING|'& |
                 '  "L" или "l" или "4" - ULONG|'& |
                 '  "R" или "r" или "8" - REAL|'& |
                 '  "1"                 - BYTE|'& |
                 '  "2"                 - USHORT|'& |
                 '  "6" (специальный)   - STRING(6)||'& |
                 'Для типа "W" может быть задана длина строки Unicode (в символах)'& |
                 'Для типа "S" ДОЛЖНА быть задана длина строки (в байтах)' |
            , 'GetFromAddr - ERROR.', ICON:HAND, '&STOP|&IGNORE') = 1 THEN
        HALT(999)
      END
      Return('')
  End


WideCStr_To_Str  Function(*CString cstr, Long Leng=-1) !, String
buf  CString(2048)
  Code
    WideCharToMultiByte(0, 0, cstr, Leng, buf, Size(buf))
  Return (buf)
Компьютер имеет то преимущество перед мозгом, что им пользуются...
Ответить