Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.50/6: Рейтинг темы: голосов - 6, средняя оценка - 4.50
1386 / 842 / 91
Регистрация: 08.02.2017
Сообщений: 3,585
Записей в блоге: 1

Безопасные указатели

25.02.2024, 17:29. Показов 2325. Ответов 22
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет! Давно не писал сюда. Тему указателей, я затрагивал не раз, но желаемого консенсуса не смог достичь из этой темы, а именно безопасных указателей.. Может уместнее сказать линк, поскольку указатель - это и адресс в памяти, а линк наверное более объемлющее понятие, подходящее для переменной ссылочного типа, о чем пойдет речь. Что я имею в виду под безопасным, это такой линк, который можно инициализировать в переменную уровня модуля, и использовать в разных процедурах. Такой линк можно создать с помощью массива , но в случае сбоя или ошибки он непременно вызовет полный краш. В условиях прги на VB6 это не является проблеммой, поскольку скомпилированная программа должна существовать без ошибок, а любая ошибка - так или иначе крах. В VBA немного другая ситуация, там в случае не исправленной ошибки VBA также падает, (также может случиться что-то вроде "потери состояния"), что в общем не должно приводить к краху осноного приложения. Но вот в частности, всеж-таки это проихсодит при наличии лишних указателей в памяти. Однако сегодня внезапно я обнаружил, возможность создать, такие безопасные указатели/линки с помощью типа variant.
Решил я проверить, как работает передача разных переменных в функцию, с аргументами заданными как variant. И как выяснилось довольно не плохо работает. Как выясниось variant позволяет передавать по ссылке аргументы любого (стандартного) типа (Byte, Integer и т.д.). Я раньше задумывался над тем, как в VB реализовать аргумент по типу As Any, и можно сказать Variant в какой-то мере позволяет это сделать. Также, можно создать ссылку-указатель на уровне модуля и использовать ее в разных процедурах и при случае сбоя или ошибки, она не вызовет полный крах приложения. Есть, конечно нюансы. Вариантные пременные-ссылки должны быть в стеке, т.е. передаваться как аргументы,в ином случае ссылка слеатает.
Другой нюанс в ниже приведенном коде. Ключевое действие происходит в процедуре "Пример" и "testtest". После строчки
"vPtr1 = StrPtr(s) + 2 * 2" если в переменной vPtr2 поменят код символа, то должна меняться 3я буква в строке "s". В 32bit работат, в x64 почему-то нет, надеюсь на комментарии
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
#If Win64 Then
    Const ptrSz As LongPtr = 8
    Const varSz As LongPtr = 24
#Else
    #If Not VBA7 Then
        Private Enum LongPtr
            [_]
        End Enum
    #End If
    Const ptrSz As LongPtr = 4
    Const varSz As LongPtr = 16
#End If
Private Declare PtrSafe Function ArrPtr Lib "VBE7" Alias "VarPtr" (var() As Any) As LongPtr
Private Declare PtrSafe Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (Destination As Any, Source As Any, Optional ByVal Length As LongPtr = ptrSz)
Private Type tpVariant
    vt As Integer
    r1 As Integer
    r2 As Integer
    r3 As Integer
    pt As LongPtr
    r4 As LongPtr
End Type
Private Enum vt
    VT_RefInt = &H4002 '16386
    VT_RefLng = &H4003 '16387
    VT_RefSng = &H4004 '16388
    VT_RefDbl = &H4005 '16389
    VT_RefCur = &H4006 '16390
    VT_RefStr = &H4008 '16392
    VT_RefByt = &H4011 '16401
    VT_RefLngLng = &H4014 '16404
#If Win64 Then
    VT_RefPtr = VT_RefLngLng
#Else
    VT_RefPtr = VT_RefLng
#End If
End Enum
 
Private blInit As Boolean
Private vLnk(1)
 
Sub Пример()
    If Not blInit Then
        InitVarLink vLnk(0), vLnk(1), VT_RefInt
        blInit = True
    End If
    testtest vLnk(0), vLnk(1)
End Sub
 
Sub testtest(ByRef vPtr1 As Variant, ByRef vPtr2 As Variant)
    Dim s$
    
    s = "abcd"
    
    vPtr1 = StrPtr(s) + 2 * 2 'установка указателя на 3 буву в строке s
    
    Stop
End Sub
 
Sub InitVarLink(v1, v2, tp%)
    MakeVarLink 0, v2, tp                     'создание вариантной ссылки нужног типа
    MakeVarLink VarPtr(v2) + 8, v1, VT_RefPtr 'создание ссылки на указатель первой (v2) ссылки
End Sub
Sub MakeVarLink(ByVal ptr As LongPtr, ByRef vLnk As Variant, ByVal vt As Integer)
    Dim tpVar As tpVariant
    tpVar.vt = vt
    tpVar.pt = ptr
    CopyMemory vLnk, tpVar, varSz
End Sub
2
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
25.02.2024, 17:29
Ответы с готовыми решениями:

Безопасные скрипты
Вообщем обясните как защититься от XSS SQL... и прочего зла)

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

безопасные среды
вопрос в том,в чем состоит понятие "безопасные среды" именно для распределенных БД...в инете нашла пару интересных вариантов,...

22
1386 / 842 / 91
Регистрация: 08.02.2017
Сообщений: 3,585
Записей в блоге: 1
11.10.2024, 22:13  [ТС]
Студворк — интернет-сервис помощи студентам
Поскольку, как недавно обнаружилось, оператор With основан на ByRef-механизме (назовем его так), появилась идея у меня, что если функцию объявить как Static, тогда все переменные в ней будут не стираемые, а значит и With-переменные тоже будут нестираемые, т.е. их можно будет использовать как не освобождаемые BtRef-ссылке. Может быть не совсем понятно, но, в принципе на деле все немножко не так, хотя в принципе эти неосвобождаемыеую ссылку удалось таки получить, поскольку выяснилось еще коя-что. Вот что:
Если в статик переменных прописать UDT-переменную (самую первую), то на определенном отрицателном смещении (оно бывает разное) от первой переменной в стеке прописывается указатель на эту переменную. Если этот указатель поменять, то UDT переменная будет мапиться уже на этот новый указатель. Такая фишка наблюдается только в самой первой группе статик -переменных. К слову сказать каждая группа (строка объявления) статик переменных находится как бы в отдельном стеке и в др. группах я к сож. не обнаружил такой же фишки.
Проверял сначала на VBA, работает не совсем стабильно если выполнять пошагово, но при обычном выполнении вроде бы нормально. На VB6 в IDE это тоже работает. Пример:
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
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Private Type tpLongPtr
    lp As Long
End Type
 
Sub testSwapString()
    Dim s1$, s2$
    s1 = "Hello"
    s2 = "World"
    SwapString s1, s2
    Debug.Print s1; " "; s2
End Sub
Private Sub SwapString(s1$, s2$)
    SwapString_ s1, s2
End Sub
Private Sub SwapString_(s1$, s2$, Optional lp1 As Long, Optional ByVal lp0 As Long)
    Static pRef1 As tpLongPtr
    Static pRef2 As tpLongPtr
    Dim i&, blOk As Boolean
    
    If pRef1.lp > 1 Then
    Else
        'устанавливаем ByRef указатель pRef1 на ByRef указатель lp1
        lp1 = VarPtr(pRef1)
        For i = 4 To 128 Step 4
            CopyMemory lp0, ByVal VarPtr(pRef1) - i, 4
            If lp0 = lp1 Then
                blOk = True
                Debug.Print i
                CopyMemory ByVal VarPtr(pRef1) - i, VarPtr(lp0) - 4, 4
                Exit For
            End If
        Next
        If Not blOk Then
            MsgBox "Не удалось найти указатеь pRef1"
            Exit Sub
        End If
    End If
    lp0 = StrPtr(s1)
    pRef1.lp = VarPtr(s1)
    lp1 = StrPtr(s2)
    pRef1.lp = VarPtr(s2)
    lp1 = lp0
End Sub
2
1386 / 842 / 91
Регистрация: 08.02.2017
Сообщений: 3,585
Записей в блоге: 1
12.10.2024, 10:22  [ТС]
Но это вроде бы не правильно, потому, что если сделать 2 процедуры, с подобными манипуляциями, то во второй уже не находится нужный уазатель, могжет быть даже вылет в исключение.

Добавлено через 2 часа 1 минуту
Цитата Сообщение от testuser2 Посмотреть сообщение
каждая группа (строка объявления) статик переменных находится как бы в отдельном стеке
Хрень написал, все статик переменные всех процедур находятся в одном стеке, как бы скрытые глобалки, вот это как. Поэтому в самой верхней процедуре в модуле первая статик переменная будет началом стека и если поменять этот указатель (как я показывал выше), то будет бардак со статик переменными во всех процедурах

Добавлено через 1 час 30 минут
Static и Public в одном стеке
Code
1
2
3
4
Module1 Static Var:          309690624 
Module1 Public Var:          309690592 
Module2 Static Var:          309690648 
Module2 Public Var:          309690656
0
1386 / 842 / 91
Регистрация: 08.02.2017
Сообщений: 3,585
Записей в блоге: 1
27.07.2025, 07:42  [ТС]
Стоит сказазть и об этом, на ряду с тем, поскольку в том модуле как раз используются безопасные указатели (или ссылки, референсы, как удобнее). Фокус заключается в установке параметра .cLocks = 1 дескриптора массива, после чего дескриптор массива не освобождается при выходе из зоны видимости (как принято говорить у программистов), а это значит, массив после этого можно использовать как безопасную ссылку.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
27.07.2025, 07:42
Помогаю со студенческими работами здесь

Безопасные запросы по АПИ
Здравствуйте уважаемые форумчане. Столкнулся с такой проблемой: был взломан сайт и украдены логин и пароль от базы. Т.к. это была моя...

Самые безопасные оптимизаторы и деинсталляторы
Я решил сделать небольшой анализ "Оптимизаторов" и "Деинсталляторов" для того, чтобы найти самые безопасные из них. Учтите, что этот анализ...

Какие ЖК мониторы сейчас самые безопасные?
Раньше были наклейки вроде ТСО 99 и т.п., а сейчас как выбрать самый безопасный монитор?

Динамическое программирование: найти безопасные пути для кузнечика
кузнечик может прыгать на 1,2 или 3 позиции. на некоторых позициях сидят лягушки, которые съедают кузнечика. необходимо подсчитать, сколько...

Указатели и указатели на указатели, а также типы данных
Недавно начал изучать Си, перешел с Delphi. Много непонятного и пока процесс идет медленно. Накачал литературы, буду изучать) Щас...


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

Или воспользуйтесь поиском по форуму:
23
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru