Lib.RegisterFunction

From SunFlurry wiki
Revision as of 12:11, 8 June 2023 by Admin (talk | contribs) (1 revision imported)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
  RegisterFunction (Импорт функции)
Объект:Библиотека
Статус разработки: Реализована
Тип:Функция
Обращение к БД:Нет
Исключения:Невозможно превратить в строку, функция не найдена
Визуальность:Нет

Функция производит попытку импорта функции по ее имени из библиотеки, если функция найдена, она будет добавлена к функциям, которые возможно вызвать из данного объекта. Для функции задается, если необходимо, список и типы данных аргументов, а также тип данных возвращаемого значения, если оно присутствует.

Синтаксис

Lib.RegisterFunction(<Имя функции (STRING)><Способ вызова (STRING)>="Stdcall",<Аргументы функции (STRING)>,<Возвращаемое значение (STRING)>)

Аргументы

  • <Имя функции (STRING)> - Аргумент задает точное имя импортируемой функции и, если необходимо, локальное имя функции, с помощью которого она может быть вызвана из программы. Формат аргумента следующий: <Имя функции для импорта>[:<Локальное имя для вызова>]. Если часть с локальным именем не используется, функция будет зарегистрирована под своим именем импорта.
  • <Способ вызова (STRING)> - (необязательный аргумент) Аргумент задает способ вызова функции (см. статью для дополнительной информации). Возможны следующие значения аргумента:
    • stdcall (x86,x64) -- стандартный способ вызова функций Windows, используется по умолчанию. Для x64 является единственным доступным способом вызова.
    • cdecl (x86) -- используется при вызове функций, скомпилированных с помощью C или C++. Система позволяет использование такого способа вызова вместо вызовов stdcall, но не наоборот. Если для библиотек, скомпилированных со способом вызова cdecl указать способ вызова stdcall, можно получить порчу памяти или привести клиент нерабочее состояние.
    • fastcall (x86) -- используется при вызове функций, скомпилированных с помощью C или C++. Несовместим с другими способами вызова.
    • register (x86) -- используется при вызове функций, скомпилированных с помощью Delphi или Free Pascal. Несовместим с другими способами вызова. Важно понимать, что, возможно, придется пометить некоторые параметры при вызове таких функций с помощью префикса "+" (см. ниже).
    • vectorcall (x86,x64) -- способ вызова, оперирующий длинными числами (128 бит), в данный момент не поддерживается.
  • <Аргументы функции (STRING)> - (необязательный аргумент) Задает список и тип аргументов, передаваемых функции. Строка имеет следующий формат: <Аргумент 1>,<Аргумент 2>,.... Где аргумент имеет следующий формат: [<Префиксы типа данных>]<Тип данных аргумента>[<Размер типа данных>]. Далее даются все возможные префиксы и наименования типов данных:
    • ^ (префикс) -- определяет то, что аргумент будет являться ссылкой (указателем, pointer) на данные, а не самими данными.
    • ^^ (префикс) -- определяет то, что аргумент будет являться ссылкой (указатель, pointer) на ссылку на данные, а не самими данными. Префикс можно эмулировать с помощью манипуляции с буфером данных.
    • @ (префикс) -- определяет то, что аргумент будет являться ссылкой (указателем, pointer) на данные, а не самими данными. Также помечает аргументы "by ref", т.е., аргументы, значение которых может быть изменено функцией и должно быть передано назад в вызывавшую программу. Важно: без этого префикса, измененные функцией значения будут утеряны. Префикс может дополняться префиксом ^, если необходимо.
    • U (префикс) -- используется для типов I или N, указывает на то, что данные представляют собой беззнаковое число (по умолчанию число со знаком)
    • # (префикс) -- определяет то, что выделение памяти для аргументов (к примеру, для передаваемых строк), будет происходить с помощью системной функции GlobalAlloc. Некоторые типы вызовов могут требовать такой подход.
    • ~ (префикс) -- определяет то, что выделенная под аргумент память не будет освобождена после выполнения функции. Этой опцией нужно пользоваться с особой осторожностью, так как неверное ее использование может привести к бесконтрольным утечкам памяти.
    • + (префикс) -- определяет то, что данный аргумент всегда будет передаваться в стек, а не с помощью регистра процессора. Флаг имеет значение только для способа вызова функции register. Для его использования необходимо полностью понимать, как работает вызов функции (calling convention) такого типа. Обычно нет необходимости в использовании этого префикса, система сама правильно определит какие аргументы будут передаваться в стек, а какие с помощью регистров.
    • I<Размер в битах> или Int<Размер в битах> (наименование типа данных) -- задает целый тип аргумента. Размер может принимать следующие значения: 8, 16, 32, 64.
    • N или Native (наименование типа данных) -- задает целый тип аргумента с размером, задаваемым текущей архитектурой исполнения приложения. Для x86 длина поля будет представлять 32 бита, для x64 -- 64 бита.
    • R<Размер в битах> или Real<Размер в битах> (наименование типа данных) -- задает вещественный тип аргумента. Размер может принимать следующие значения: 32 (одинарная точность), 64 (двойная точность), 80 (расширенная точность). Расширенная точность не поддерживается при стандартных вызовах "x64" функций, при написании расширения программы, можно пользоваться, к примеру, ссылкой на вещественное число (P) и получение его из буфера.
    • B<Размер в битах> или Bool<Размер в битах> (наименование типа данных) -- задает булевый тип аргумента. Размер может принимать следующие значения: 8, 16, 32, 64.
    • P или Pointer (наименование типа данных) -- задает тип данных указателя на данные. Для x86 длина поля будет поставлять 32 бита, для x64 -- 64 бита. При вызове функцией в аргументы такого типа удобно передавать объекты буфера или записи. Также можно задавать аргументы с типом Функция обработного вызова, что может часто использоваться в процессе выполнения сложных функций.
    • SZ<Размер в байтах> или SZW<Размер в словах> (наименование типа данных) -- задает аргумент с типом строка, заканчивающаяся нулевым символом. Строка может иметь формат ANSI (SZ) или UTF-16 (SZW). Строки всегда должны быть объявлены с префиксом ^ (ссылка на данные). Размер может принимать нулевое значение, если заранее неизвестно, строка какого размера будет использоваться. В случае нулевого размера, однако, при подготовке аргумента, размер будет выделен точно под строку. Кроме строковых значений, система принимает также буферы или записи (для которых вызов выполняется несколько быстрее, чем для строк).
    • S<Размер в байтах> или SW<Размер в словах> (наименование типа данных) -- задает аргумент с типом строка фиксированной длины. Строка может иметь формат ANSI (S) или UTF-16 (SW). Строки всегда должны быть объявлены с префиксом ^ (ссылка на данные). Размер может принимать нулевое значение, если заранее неизвестно, строка какого размера будет использоваться. В случае нулевого размера, однако, при подготовке аргумента, размер будет выделен точно под строку. Кроме строковых значений, система принимает также буферы (для которых вызов выполняется несколько быстрее, чем для строк).
  • <Возвращаемое значение (STRING)> - (необязательный аргумент) Имеет формат одного аргумента функции (см. выше), если аргумент опущен, возвращаемое функцией значение будет игнорировано (функция не возвращает значения).

Примеры

Function ПолучитьИмяПользователя()
  aAdvapi32:=Lib.Load("advapi32.dll");
  aAdvapi32.RegisterFunction("GetUserNameW:GetUserName","stdcall","@SZW,@UN","B32");
  аИмя:=RepeatStr(" ",256);
  аДлина:=Length(аИмя);
  аДлина0:=аДлина;
  While not aAdvapi32.GetUserName(аИмя,аДлина) Do
    //Недостаточный размер буфера
    аИмя:=RepeatStr(" ",аДлина0*2);
    аДлина:=Length(аИмя);
    аДлина0:=аДлина;
  EndDo;
  Exit аИмя;
EndFunction;

Message(ПолучитьИмяПользователя());