Типы входных параметров и возвращаемых значений
m — знаковое целое 64 бита — INT64, LONGLONG, ...q — беззнаковое целое 64 бита — UINT64, ULONGLONG, ...
l — знаковое целое 32 бита — LONG, INT, BOOL, ...
u — беззнаковое целое 32 бита — ULONG, UINT, DWORD, ...
h — хэндл, дескриптор — HANDLE, HWND, HMODULE, HINSTANCE, HICON, ... — 32 бита (x86) или 64 бита (x64)
p — указатель, для чисел то же, что u (x86) или q (x64), но также можно использовать для передачи объекта (IDispatch *) и строки.
n — знаковое целое 16 бит — SHORT
t — беззнаковое целое 16 бит — USHORT, WORD, WCHAR, OLECHAR, ...
c — знаковое целое 8 бит — CHAR
b — беззнаковое целое 8 бит — UCHAR, BYTE, ...
f — дробное число одинарной точности (32 бита) — FLOAT
d — дробное число двойной точности (64 бита) — DOUBLE
w — строка в Юникоде — BSTR, LPWSTR, LPOLESTR, OLECHAR *, WCHAR *, ...
s — строка в кодировке ANSI/Windows по умолчанию — LPSTR, LPCSTR, CHAR *, ...
z — строка в кодировке OEM/DOS по умолчанию — LPSTR, LPCSTR, CHAR *, ...
v — указатель на структуру VARIANT
Примечания
- Подробнее о строковых типах см. здесь.
- Кроме хэндлов и указателей, есть и другие типы, меняющие свою битность с битностью процесса. Например, LRESULT, LPARAM, WPARAM, SIZE_T. Для них также лучше использовать тип h или p, чтобы код скрипта корректно работал при его выполнении как 32-, так и 64-битным интерпретатором.
- Типам m и q (а также h и p в x64) в скриптах соответствовали бы типы VT_I8 и VT_UI8. Движками JScript и VBScript эти типы не поддерживаются, что ограничивает возможности работы с 64-битными целыми. Пока значение возвращаемого функцией числа это позволяет, DWX преобразует его к типам VT_I4 (знаковое целое 32 бита) либо VT_R8 (дробное число двойной точности). Поскольку мантисса VT_R8 имеет только 53 бита, этот тип не может отобразить все числа в диапазоне 64-битного целого. В таком случае возвращается тип VT_I8 или VT_UI8. Всё, что можно с ними сделать в скрипте, — передать как аргумент в какой-то другой метод или вывести значение числа в WScript.Echo либо MsgBox. Никакие расчёты с ними невозможны.
- Когда большое целое возвращается как VT_R8 и вы хотите посмотреть его значение в диалоговом окне, оно может отображаться неточно из-за ограничения на число знаков после запятой в строковом представлении дробного числа. Поэтому, например, число 9223372036854775808 может отобразиться как 9,22337203685478E+18 вместо 9,223372036854775808E+18. Однако само число в переменной не округляется и остаётся точным.
- Если значение 64-битного целого не укладывается ни в один из доступных числовых типов, можно указать его в виде строки, десятичной или шестнадцатеричной (с префиксом 0x).
DWX.Register("lib.dll", "func", "i=m") DWX.func("0xFFFFFFFFFFFFFFFF") DWX.func("-0x7FFFFFFFFFFFFFFF") DWX.func("18446744073709551615") DWX.func("-9223372036854775807")
Выходные параметры
M — указатель на число (его адрес в памяти) — LONGLONG *, PLONGLONG и т.п.Q — то же — ULONGLONG *, PULONGLONG, ...
L — то же — LONG *, LPLONG, ...
H — то же — HANDLE *, PHANDLE, LPHANDLE, ...
U — то же — ULONG *, LPDWORD, ...
P — то же
N — то же — SHORT *
T — то же — USHORT *, LPWORD, WCHAR *, OLECHAR *, ...
C — то же — CHAR *, ...
B — то же — UCHAR *, LPBYTE, ...
F — то же — FLOAT *, PFLOAT
D — то же — DOUBLE *, PDOUBLE
W — выходная строка в Юникоде
S — выходная строка в ANSI
Z — выходная строка в OEM
Примечания
- Использование выходных типов для чисел имеет смысл для скриптовых движков, которые передают переменные в метод по ссылке, как это делает VBScript. В этом случае DWX может передать функции указатель на значение переменной, которое функция может изменить. В движках, где аргументы передаются по значению, как в JScript, методу передаётся копия числа, поэтому изменить оригинал нет возможности. В этом случае решением будет выделение нужного количества памяти, например, методом MemAlloc, передача функции указателя на эту память (используя тип p) и затем, после вызова функции, считывание помещённого ею туда числа методом NumGet.
- Некоторые движки копируют строки при передаче их в метод; в этом случае использование выходных типов для строк также теряет смысл. Решение аналогично: выделение памяти, передача указателя на неё типом p и затем считывание оттуда строки методом StrGet.