Путь к истине

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Путь к истине » Программирование » Функции для работы с указателями из msvbvm60


Функции для работы с указателями из msvbvm60

Сообщений 1 страница 5 из 5

1

По этой теме в инете громадное колличество статей, я взялся написать статейку только потому, что
хочу по своему это объяснить.
В VB6 есть библиотечка msvbvm60 , можно сказать, это сердце VB6 . В этой библиотечке почти тысяча функций.
По непонятной причине, в VB6 не реализована работа с указателями. Хотя функция взятия адреса есть -
VarPtr(a) !!!
Но взять адрес мало, надо научиться читать то, что в этом адресе записано и уметь записать данные в
нужный адрес. В msvbvm60 для этого есть всё необходимое. Для каждого типа переменной есть своя функция.
Начнём проект с декларации функций для записи и чтения по нужным адресам.

Private Declare Sub PutMem1 Lib "msvbvm60" (ByVal Addr As Long, ByVal NewVal As Byte)
Private Declare Sub PutMem2 Lib "msvbvm60" (ByVal Addr As Long, ByVal NewVal As Integer)
Private Declare Sub PutMem4 Lib "msvbvm60" (ByVal Addr As Long, ByVal NewVal As Long)
Private Declare Sub PutMem8 Lib "msvbvm60" (ByVal Addr As Long, ByVal NewVal As Currency)
Private Declare Sub GetMem1 Lib "msvbvm60" (ByVal Addr As Long, RetVal As Byte)
Private Declare Sub GetMem2 Lib "msvbvm60" (ByVal Addr As Long, RetVal As Integer)
Private Declare Sub GetMem4 Lib "msvbvm60" (ByVal Addr As Long, RetVal As Long)
Private Declare Sub GetMem8 Lib "msvbvm60" (ByVal Addr As Long, RetVal As Currency)

Как видим в названиях функий указанно колличество байт. То есть PutMem1 - записать число типа Byte ,
а PutMem4  типа Long !!!
Теперь на форму проекта киньте четыре лябеля и кнопку.
А теперь  объявим нужные переменные для нашей демки:

Dim s11, s22, s33, s44 As Variant
Dim a As Byte, b As Integer, c As Long, d As Currency

Теперь функция для кнопки, она выведет результаты работы демки:

Private Sub Command1_Click()
Label1.Caption = s11
Label2.Caption = s22
Label3.Caption = s33
Label4.Caption = s44
End Sub

А теперь и самое главное !:

Private Sub Form_Load()

По адресам переменных полученных функцией VarPtr записываем значения, обратите внимание, все переменные разных
типов и для них используются различные функции!!!

PutMem1 VarPtr(a), 105
PutMem2 VarPtr(b), 3892
PutMem4 VarPtr(c), 543543
PutMem8 VarPtr(d), 1054357675

А теперь прочитаем значения по адресам переменных.

GetMem1 VarPtr(a), s11
GetMem2 VarPtr(b), s22
GetMem4 VarPtr(c), s33
GetMem8 VarPtr(d), s44

End Sub

Как вможно заметить GetMem1 VarPtr(a), s11 абсолютно равносильно  s11 = a  ,
а PutMem1 VarPtr(a), 105 равносильно a = 105 )))
В реальной практике мне ни разу не довелось использовать указатели, работая в VB6 отлично и без них
можно обойтись. Но всё таки возможно в каких то очень редких случаях это может понадобиться  и
самое главное, что такая возможность имеется !
http://s9.uploads.ru/t/1YPDF.jpg

0

2

Наконец-то! Константин, огромное Вам спасибо! Так понятно и точно раскрыли тему! В сети всё вокруг да около, примеры, которые я находил, не работают. Один пишет для 1,2,4 и 8 одинаковый тип NewVal - Long. Теперь ясно, почему всё время слетало. Спасибо!!!

0

3

А можно вопрос в дораскрытии этой темы?
VB6 имеет еще одну интересную намётку, которую тоже почему-то не развили -
переводить пользовательские типы данных в строку.

Представьте такой код:

Код:
Type ВидКарты
   ...
End Type
Dim Карта as ВидКарты
MsgBox Len(Карта)

- и он вернёт именно длину переменной пользовательского типа в байтах (ну или как там).

Идём дальше:

Код:
MsgBox Str(Карта)

- и всё. Ошибочка. И как ни крути с Public Module, обойти мне её так и не удалось.
Иду на извращение:

Код:
Open "Temp.txt" For Output As 5: Close 5  'чтобы очистить файл
Open "Temp.txt" For Binary As 5
    Put #5, 1, Карта  'всобачиваем пользовательский тип в файл КАК ТЕКСТ - vb это может!!!
    Seek #5, 1         'Возвращаемся к первой позиции
    ТекстКарты$ = Input(LOF(5), #5) 'Считываем этот псевдо-текст в текстовую переменную
    MsgBox Mid(ТекстКарты, 15, 10)  'Выводит фрагмент текста из переменной (сначала она в ужасных символах, которых MsgBox не понимает)
Close 5
Kill "Temp.txt"

- это РАБОТАЕТ, т.е. VB6 прекрасно конвертирует пользовательский тип в строку, чтобы вставить его содержимое в файл!!! Но разве нельзя это сделать через какой-нибудь CopyMem без создания промежуточного файла?!

Информации нет Нигде! Может, Вы сталкивались?

0

4

Наверно только через файл..  Через CopyMemory  не получится. Так как Запись в VB это всего лишь удобство для программиста, а в не реальная линейная структура. По сути, запись это только групировка реальных имён.
Если в записи есть строковая переменная, то её можно конечно скопировать, но нет никакого смысла. так как можно просто так присвоить.
Вот примерчик реальный по функции копирования переменной из Записи в строковую переменную .

Код:
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Dim r As String

Private Type record
x1 As Integer
s1 As String
End Type
Dim tx As record

Private Sub Command1_Click()

r = "987654321"
tx.s1 = "proba"
tx.x1 = 223

Call CopyMemory(ByVal StrPtr(r), ByVal StrPtr(tx.s1), 10)
Text1.Text = r
Debug.Print tx.s1

End Sub

Адрес строковой переменной берётся функцией StrPtr() !
Очень нестабильно, через раз работает... Но у меня урезанная портабельная версия VB , на мою форточку уже не устанавливается нормальная версия, я уже давно перешёл на VB.net.
Вот скриншот результата.
http://sg.uploads.ru/t/ZpgFP.jpg

0

5

Большущее спасибо!  В общих чертах понятно.
Буду действовать именно через файл!

0


Вы здесь » Путь к истине » Программирование » Функции для работы с указателями из msvbvm60