Строки
В JScript и VBScript используются строки типа BSTR. Это строка в Юникоде, т.е. код каждого символа занимает 2 байта. За последним символом расположен ограничитель — 2 нулевых байта. Кроме того, перед первым символом находится 4-байтное число, содержащее длину строки в байтах (без учёта нулевых на конце). Указатель, содержащийся в скриптовых строковых переменных, является адресом первого символа такой строки (т.е. байты, содержащие длину строки, как бы остаются за кадром).Передать строку можно тремя способами:
- Входная строка: w, s, z. Для типов s и z строка копируется с конвертацией в соответствующую кодировку, и API-функция получает указатель на эту копию. После завершения работы функции память, запрошенная под копию строки, освобождается, т.е. эта копия перестаёт существовать. В случае w функции передаётся указатель на оригинал строки.
- Выходная строка: W, S, Z. Передаётся указатель на оригинал строки, но S и Z предварительно конвертируются (на месте). После завершения функции строки S и Z конвертируются обратно в Юникод, у них измеряется длина, а у строки W только измеряется длина. Длина (в байтах) записывается перед строкой. Без этой последней операции потом в скрипте будут глюки, например, при конкатенации этой строки с другими.
- Указатель: p. Это самый простой способ. Передаётся указатель на оригинал строки, без конвертации. После завершения функции нет ни конвертации, ни корректировки длины. Так что если функция туда что-то запишет, оно там будет в нетронутом виде. Здесь строка фактически является просто буфером в памяти для хранения любых данных.
Может показаться, что это то же самое, что w, но это не так. Разница в том, что параметр, объявленный как p, принимает не только строковые переменные, но и числовые (адрес строки в виде числа).
Вернуть строку можно также по-разному:
- p — получаем числовую переменную, содержащую указатель на строку, которую вернула функция.
- w, s или z — получаем строковую переменную, содержащую указатель на копию этой строки. Строки s и z копируются с конвертацией в Юникод.
Оригинал строки не освобождается, т.к. DWX не может знать, каким способом была выделена под неё память. Если для вас это имеет значение, то возвращайте строку типом p, копируйте её в переменную методом StrGet и затем освобождайте исходную строку тем способом, какой рекомендован в описании вызываемой функции.
Вызовы API, принимающие строковые аргументы, как правило, представлены в двух вариантах - например, MessageBoxA и MessageBoxW. Использование в скриптах юникодовских вариантов, с окончанием W, представляется более логичным, т.к. при этом нет дополнительных перекодировок строк туда и обратно.
Выходная строка, как и прочие выходные параметры, предназначена для того, чтобы функция API в неё что-нибудь записала, так что её длина должна быть соответствующей.
Использование строк как буферов памяти может работать или нет в зависимости от того, как внутри скриптового движка реализована работа со строками. Предпочтительнее выделять память методом MemAlloc, т.к. она будет под вашим полным контролем.