* По умолчанию локальные массивы фиксированного размера создаются VB6 в куче; в стеке лежит лишь 24-байтный дескриптор (типа SAFEARRAY). Это позволяет использовать громадные локальные массивы, не опасаясь переполнения стека.
Намного эффективнее, когда это возможно, размещать массив целиком в стеке. Для этого его надо обрамить UDT-обёрткой:
- Код: Выделить всё
Option Explicit
Private Type a
b(10) As Long
End Type
Sub Main()
Dim a As a, b(10) As Long, sp As Long
Debug.Print Hex(VarPtr(sp)) 'стек
Debug.Print Hex(VarPtr(b(0))) 'куча
Debug.Print Hex(VarPtr(a.b(0))) 'стек
End Sub
В этом случае дескриптор (который типа SAFEARRAY) не создаётся вовсе. Тем более удивительно, что удаётся успешно скастовать такой обёрнутый массив к типу Variant.
* Вроде бы не общеизвестно, что в виндовых прогах сегмент fs: указывает не в безвоздушное пространство, а на TEB (Thread Environment Block). В частности, fs:0 указывает на начало цепочки обработчиков SEH, fs:1Ch -- на окружение, fs:20h -- содержит PID, fs:24h -- TID и т.д.
fs:18h указывает на адрес этого TEB в основном адресном пространстве. В частности, чтобы не вызывать ассемблерную вставку для каждого обращения к полям TEB, достаточно прочитать адрес из поля fs:18h и скопировать данные с этого адреса в соответствующим образом объявленную UDT.
В TEB (и PEB, на который тот ссылается), хранится уйма полезной информации, доступной для чтения и записи. Например, записью в PEB можно переопределить стандартные хендлы. (Кому-то на форуме этого очень хотелось, не могу сейчас найти тот пост.)
* И теперь, собственно, возникает вопрос: где взять объявления структур PEB и TEB, если их нет даже в DDK? Вот из этой ссылки и развился данный пост
Бесценный ресурс для всех, кто любит ковыряться в кишках Винды: http://www.acc.umu.se/~bosse/ntifs.h