Дата публикации статьи: 22.05.2004 11:54

Гергерт Сергей
Функции VB для работы с указателями

    Поработав энное время с VB, начинаешь немного жалеть, что в нём нет того-то, или того-то, и потому приходится идти длинными обходными путями. Других достоинств языка это не умаляет, но всё же. Я вот порой думаю: как было бы здорово, если бы была встроенная работа с указателями, если бы можно было кастовать1 lParam, если бы не нужна была CopyMemory... Но не может же откомпилированный экзешник обойтись без работы с указателями, думал я... Думал, думал... А потом решил внимательно посмотреть, какие функции экспортирует msvbvm60.dll2 (потому что отвязаться от неё всё равно не получится, так может ещё что вытрясем). И нашёл массу интересного. После нескольких десятков крушений IDE разобрался с назначением некоторого количества функций (продолжаю разбираться с остальными, IDE рушится с завидным постоянством :)).
    Вот они, самые важные из изученных и понятых.

Public Declare Function GetMem2 Lib "msvbvm60" (ByVal pSrc As Long, ByVal pDst As Long) _
As Long
Public Declare Function GetMem4 Lib "msvbvm60" (ByVal pSrc As Long, ByVal pDst As Long) _
As Long
Public Declare Function GetMem8 Lib "msvbvm60" (ByVal pQWORDSrc As Long, ByVal pQWORDDst _
As Long) As Long
Эта группа функций ожидает два указателя: куда копировать и откуда копировать. Сишный эквивалент:
int __stdcall GetMem4 (int* src, int* dst)
{
  *dst = *src;
  return 0;
}

    Копирование производится с максимальной для процессора эффективностью. Никаких проверок правильности аргументов, а значит, максимальная скорость. Правда, если передадите неверный указатель, то всё рухнет :)

Public Declare Function PutMem2 Lib "msvbvm60" (ByVal pDst As Long, ByVal NewValue As Long) _
As Long
Public Declare Function PutMem4 Lib "msvbvm60" (ByVal pDst As Long, ByVal NewValue As Long) _
As Long
Public Declare Function PutMem8 Lib "msvbvm60" (ByVal pQWORDDst As Long, _
ByVal NewValueLowDWORD As Long, ByVal NewValueHighDWORD As Long) As Long

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

int __stdcall PutMem4 (int* dst, int NewValue)
{
  *dst = NewValue;
  return 0;
}

    Ничуть не менее эффективно.
    Есть ещё несколько функций, которые я не стал здесь рассматривать - например, GetMemStr сотоварищи. Её действие абсолютно эквивалентно простому присваиванию str1 = str2.
Эти 6 функций дают нам, фактически, прямую работу с указателями (включая арифметику), эффективность которой очень близко приближается к низкоуровневым языкам. Так что заводим себе модуль modMSVBVM и включаем его во все проекты :)
 


1 От английского to cast. (прим. редактора).
2 Основная библиотека функций Visual Basic (msvbvm60.dll от Microsoft Visual Basic Runtime 6.0 Dynamic Link Library)
.