Доступ к безымянным параметрам функций

Разговоры на любые темы: вы можете обсудить здесь какой-либо сайт, найти единомышленников или просто пообщаться...
GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Доступ к безымянным параметрам функций

Сообщение GSerg » 28.04.2004 (Ср) 9:33

Название не совсем адекватно - сделать действительно безымянные параметры на VB мне не удалось... пока... :wink:

Но такой вот интересный момент.
Допустим, мы передаём в функцию некий параметр ByRef:
Код: Выделить всё
function func(a as long) as long
  debug.print varptr(a)
end function

sub CallFunction()
  dim v as long
  debug.print varptr(v)
  func v
end sub

Запустив CallFunction, мы увидим, что в дебаге появятся два одинаковых числа. Так и должно быть.

Теперь немного изменим функцию:
Код: Выделить всё
function func(byval a as long) as long
  debug.print varptr(a)
end function

Теперь при запуске CallFunction в дебаге появятся два разных числа - и снова ничего удивительного.

Ещё раз изменим функцию:
Код: Выделить всё
function func(byval p1 as long, byval p2 as long, byval p3 as long, byval p4 as long) as long
  debug.print varptr(p1)
  debug.print varptr(p2)
  debug.print varptr(p3)
  debug.print varptr(p4)
end function

sub CallFunction()
  dim a as long, b as long, c as long, d as long
  func a,b,c,d
end sub

В дебаге появились четыре разных числа. Обращаем внимание: они идут в возрастающем порядке с интервалом 4.
Если мы теперь заменим параметры, к примеру, с Long на Integer или на Byte (все или часть - неважно) - то ничего не изменится, в дебаге будут числа, последовательно отстоящие на 4 байта. Single? То же самое. А Double? И Double подчиняется этому правилу, только следующий за Double параметр отстоит от неё не на 4, а на 8 байт.
Исключением здесь являются String. Мне не удалось установить правило образования их VarPtr, не исключено, что его нет :wink: Однако если за параметром String следует, к примеру, Long, то этот самый Long будет иметь VarPtr, на 8 байт отстоящий от параметра, который идёт непосредственно перед стринговым.
Variant не тестировал, ну его :)

Какой же вывод мы можем из этого почерпнуть?
Если у нас есть byval-параметры, среди которых нет string, то можно определить varptr первого параметра, а все остальные получать через
Код: Выделить всё
GetMem4 VarPtr([первый параметр]) + 4 * [желаемый номер параметра - 1], [куда копировать]


И таким вот незамысловатым образом можно обращаться к параметрам функции из цикла, не задумываясь о том, как эти параметры зовут! Именно эта cutting edge technology и была использована мною, чтобы отказаться от Variant ParamArray() при вызове asm-функций :)


ЗЫ: Всё это только для ByVal, ещё раз напомню! Ну и Double на 8 байт, тоже не забываем :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

corgi
ToyMan
ToyMan
 
Сообщения: 1367
Зарегистрирован: 01.10.2002 (Вт) 9:59
Откуда: Россия, Москва

Сообщение corgi » 28.04.2004 (Ср) 21:54

1. я прям таки продолжаю поражаться сколько у человека времени свободного и все такое :D :D :D (это типа был респект)
2. а теперь маленькое замечание:
конечно интересная теория, но насколько мне помнится (по-крайней мере это так было в С во времена DOS'a) оперативная память выделяется под переменные подряд, НО она начинает выделятся в совершенно произвольном месте и не факт что ее там будет достаточно для всех переменных, а если это так то начинается выделение памяти в каком-то другом месте, а в том месте где закончилось просто ставится указатель куды дале смотреть.
Отсюда следует что твой код может глючить, редко но может
зы хотя я могу ошибаться
Ничто так не ограничивает полёт мысли программиста, как компилятор

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 29.04.2004 (Чт) 8:31

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


Вернуться в Народный треп

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 107

    TopList