Выбрать главу

now = date()

-- now равно: {95,3,24,23,47,38,6,83}

-- т.е. пятница, 24 марта 1995 года, 23 часа 47 минут 38 секунд, 83-ий день года

Комментарии:

Величина, выдаваемая для года, является числом лет, начиная с 1900, а не последними 2-мя цифрами года. В 2000 году эта величина составила 100. В 2001 это было 101 и т.д. Естественно, часы и календарь вашего компьютера должны быть правильно установлены на текущие время и дату.

См. также:

time

define_c_func

Синтаксис:

include dll.e

i1 = define_c_func(x1, x2, s1, i2)

Описание:

Выдаёт номер (идентификатор) подпрограммы для заданной Си-функции или же функции машинного кода. Аргументами служат характеристики заданной функции. Выданный номер i1 используется далее в качестве первого аргумента при вызове подпрограммы c_func(), которая и запускает заданную внешнюю функцию на исполнение из Euphoria.

Когда вы задаёте характеристики Си-функции, аргумент x1 должен представлять собой адрес системной библиотеки, содержащей эту Си-функцию. Адрес библиотеки вы должны получить, заранее вызвав функцию open_dll(). Аргумент x2 задаёт имя Си-функции, которая вас интересует. Если define_c_func() не находит заданную Си-функцию, в качестве номера она выдаёт -1. На платформе Windows вы можете перед именем функции добавить символ '+'. Он показывает Euphoria, что для вызова Си-функции предусмотрены правила соглашения cdecl. По умолчанию Euphoria считает, что подпрограммы Си вызываются по правилам соглашения stdcall.

Когда вы задаёте характеристики функции машинного кода, аргумент x1 должен быть пустым рядом, "" или {}, а x2 - содержать адрес функции машинного кода. Байты машинного кода должны быть заранее размещены в участке памяти, выделенном функцией allocate(), которая и выдаёт адрес, используемый далее для размещения функции машинного кода и задания её характеристик. На платформе Windows функции машинного кода обычно следуют правилам соглашения stdcall, но если вам вместо этого необходимо использование правил cdecl, вы можете записать x2 как ряд {'+', адрес} вместо подачи значения адреса как атома.

Аргумент s1 представляет собой список типов аргументов функции. Аргумент i2 задаёт тип величины, выдаваемой функцией. Полный список типов Си, содержащий их определения, находится в библиотеке dll.e, и эти же типы могут быть использованы для назначения типов данных для функции машинного кода:

global constant C_CHAR = #01000001,

C_UCHAR = #02000001,

C_SHORT = #01000002,

C_USHORT = #02000002,

C_INT = #01000004,

C_UINT = #02000004,

C_LONG = C_INT,

C_ULONG = C_UINT,

C_POINTER = C_ULONG,

C_FLOAT = #03000004,

C_DOUBLE = #03000008

Си-функция, характеристики которой вы задаёте с использованием define_c_func(), может быть создана с помощью транслятора с Euphoria на Си. В этом случае вы сможете подавать в неё данные типов Euphoria, а она сможет выдавать данные типов Euphoria. Полный список типов Euphoria с их определениями находится в библиотеке dll.e:

global constant

E_INTEGER = #06000004,

E_ATOM = #07000004,

E_SEQUENCE= #08000004,

E_OBJECT = #09000004

Комментарии:

Аргументы Си-функций могут быть любого целочисленного типа Си и типа указателя (пойнтера) Си. Величины этих же типов и выдаются Си-функциями. Если аргументы Си-функции имеют тип двойной точности или с плавающей точкой, то в их качестве могут использоваться атомы Euphoria, а если Си-функция выдаёт величину такого типа, то эта величина может быть использована далее как атом Euphoria.

Аргументы с типами, для представления которых достаточно 4-х или меньше байтов, все подаются одним и тем же порядком, поэтому нет необходимости быть слишком пунктуальным, выбирая тот или иной тип для обозначения 4-х байтового аргумента. Тем не менее, строгое различение величин со знаком и без знака может быть важным при назначении типа величины, выдаваемой функцией.

В настоящее время не существует метода подачи в Си-функцию структуры Си по величине или получения структуры Си в качестве результата. Вы можете подать как аргумент лишь указатель на исходную структуру и получить результат в виде указателя на модифицированную структуру.

Если вы не заинтересованы в получении и использовании величины, выдаваемой Си-функцией, вам следует обратиться к паре подпрограмм define_c_proc() и c_proc().

Если вы используете интерпретатор exw.exe для вызова по правилам cdecl Си-функции, которая выдаёт величину типа с плавающей точкой, такая комбинация может не сработать. Это обусловлено особенностями компилятора Watcom C (используемого для генерации exw.exe), который нестандартным образом обходится с выдаваемыми величинами типа с плавающей точкой при работе по правилам cdecl.

Подача величин с плавающей точкой в подпрограмму машинного кода будет выполняться быстрее, если вы используете для вызова подпрограммы c_func(), а не call(), так как в этом случае нет необходимости вызывать ещё и atom_to_float64() и poke(), чтобы разместить величины с плавающей точкой в памяти.

Интерпретатор ex.exe (DOS) для обработки величин с плавающей точкой осуществляет вызовы подпрограмм Watcom (а эти подпрограммы уже сами обращаются к математическому сопроцессору, если он доступен), поэтому величины с плавающей точкой обычно подаются и считываются в паре целочисленных регистров, а не в регистрах плавающей точки. Вам, видимо, нужно будет дизассемблировать какой-нибудь код, выработанный Watcom, чтобы посмотреть в точности, как он работает, если вы решите программировать в машинных кодах.

Пример:

atom user32

integer LoadIcon

-- открываем системную библиотеку user32.dll - она содержит Си-функцию LoadIconA

user32 = open_dll("user32.dll")

-- Си-функция принимает указатель Си и целое Си в качестве аргументов.

-- Си-функция выдаёт целое Си в качестве результата.

LoadIcon = define_c_func(user32, "LoadIconA",

{C_POINTER, C_INT}, C_INT)

-- Мы использовали здесь "LoadIconA", так как знаем, что LoadIconA

-- работает по правилам stdcall, как работают

-- все стандартные подпрограммы .dll в системе WIN32 API.

-- Чтобы задать правила cdecl, мы бы использовали "+LoadIconA".

if LoadIcon = -1 then

puts(1, "LoadIconA не найдена!\n")

end if

См. также:

euphoria\demo\callmach.ex, c_func, define_c_proc, c_proc, open_dll, platform_r.htm

define_c_proc

Синтаксис:

include dll.e

i1 = define_c_proc(x1, x2, s1)

Описание:

Выдаёт номер (идентификатор) подпрограммы для заданной Си-функции или же подпрограммы машинного кода, которые подлежат вызову в качестве процедур Euphoria. Аргументами служат характеристики заданной функции (подпрограммы). Выданный номер i1 используется далее в качестве первого аргумента при вызове подпрограммы c_proc(), которая и запускает заданную внешнюю подпрограмму на исполнение из Euphoria как процедуру.

Когда вы задаёте характеристики Си-функции, аргумент x1 должен представлять собой адрес системной библиотеки, содержащей эту Си-функцию. Адрес библиотеки вы должны получить, заранее вызвав функцию open_dll(). Аргумент x2 задаёт имя Си-функции, которая вас интересует. Если define_c_proc() не находит заданную Си-функцию, в качестве номера она выдаёт -1. На платформе Windows вы можете перед именем функции добавить символ '+'. Он показывает Euphoria, что для вызова Си-функции предусмотрены правила соглашения cdecl. По умолчанию Euphoria считает, что подпрограммы Си вызываются по правилам соглашения stdcall.