1

Тема: VBScript: DynamicWrapper, передача строк по ссылке

Иногда при работе с DynamicWrapper возникают проблемы с передачей строк по ссылке функциям Win32API. Например, в JScript строка - это переменная типа Variant, которая содержит указатель на строку, т.е. адрес в памяти, где реально лежит строка. Строка в VBScript - это Variant, который содержит указатель на другой Variant, который уже содержит адрес строки (именно это дополнительное звено и даёт гибкость в плане передачи переменных в функцию - ByRef или ByVal). Но с этим, видимо, связаны и трудности при передаче строк через DynamicWrapper - вместо строки в переданной по ссылке переменной можно запросто получить мусор или получить даже обвал WSH.

Function GetData(v)
    If TypeName(v) <> "String" Then 
        GetData=v
        Exit Function
    End If
    d=CLng(0)
    pv=Wrap.strncpy(v, v, 1)
    pd=Wrap.strncpy(d, d, 1)
    Wrap.memcpy pd+8, pv+8, 8
    GetData=d
End Function

Set Wrap = CreateObject("DynamicWrapper")
Wrap.Register "user32.dll", "GetForegroundWindow",           "f=s", "r=l"
Wrap.Register "user32.dll", "SendMessageW",        "i=llll", "f=s", "r=l"
Wrap.Register "msvcrt.dll", "strncpy",             "i=wwl",  "f=c", "r=l"
Wrap.Register "msvcrt.dll", "memcpy",              "i=lll",  "f=c", "r=l"

hwnd = Wrap.GetForegroundWindow()
length = Wrap.SendMessageW(hwnd, 14, 0, 0)
title = Space(length)
res = Wrap.SendMessageW(hwnd, 13 , length + 1, GetData(title))
WScript.Echo "Длина: " & length & VBCRLF & Title

Скрипт получает заголовок окна, находящегося на переднем плане. В функции GetData используется небольшой трюк, чтобы добыть из строковой переменной реальный адрес строки, который затем и передаётся SendMessageW. Трюк заключается в копировании указателя на строку из Variant'a типа String в Variant типа Long, где он становится непосредственно доступен.
Автор идеи - YMP.

Предложения в русском языке начинаются с большой буквы и заканчиваются точкой.
В названии ветки всегда должен быть указан язык программирования или среда исполнения скрипта, если это возможно.