Книга: Язык программирования Euphoria. Справочное руководство

от C до D

от C до D

call

Синтаксис:

call(a)

Описание:

Вызывает подпрограмму на машинном языке, участок памяти с кодом которой начинается по адресу a. Подпрограмма должна запомнить содержимое всех регистров, которые она использует, а затем восстановить их в первоначальное состояние. Для обратной передачи управления интерпретатору Euphoria в этой подпрограмме должна быть предусмотрена инструкция RET (#C3).

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

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

Пример программы:

democallmach.ex

См. также:

allocate, free, peek, poke, poke4, c_proc, define_c_proc

call_back

Платформа:

WIN32, Linux, FreeBSD

Синтаксис:

include dll.e

a = call_back(i)

или

a = call_back({i1, i})

Описание:

Выдаёт машинный адрес для Euphoria-подпрограммы по её идентификатору (номеру) i. Этот адрес может затем использоваться или Windows, или внешней функцией Си (из динамически подгружаемой библиотеки (.dll) Windows или общей библиотеки (.so) Linux/FreeBSD) как 32-битный "обратный" адрес для вызова вашей Euphoria-подпрограммы. Под Windows вы можете также задать i1, доопределив тем самым формат (соглашение о форме) вызова Си для вашей подпрограммы. Если i1 записано как '+', будет применён формат cdecl. По умолчанию применяется формат stdcall. На платформах Linux и FreeBSD следует использовать только первую форму (без i1), так как там, в отличие от Windows, действует лишь стандартный формат, stdcall.

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

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

Когда ваша подпрограмма вызвана, все аргументы будут 32-битными числами без знака (положительными), поэтому вы должны объявить каждый аргумент в вашей подпрограмме как atom, независимо от вашего желания устроить более жесткий контроль. Ваша подпрограмма должна выдавать 32-битную целочисленную величину.

Вы можете также использовать адрес обратного вызова, чтобы задать подпрограмму Euphoria в качестве обработчика исключения в функции signal() под Linux/FreeBSD, когда, например, вам необходимо принять сигнал SIGTERM и произвести аккуратное завершение вашей программы. Да, действительно, иногда некоторые серверы Web выдают сигнал SIGTERM тому процессу CGI, который захватил слишком много машинного времени, и ваша программа должна быть готовой к такому повороту событий.

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

Пример программы:

demowin32window.exw, demolinuxqsort.exu

См. также:

routine_id, platform_r.htm

c_func

Платформа:

WIN32, Linux, FreeBSD

Синтаксис:

x = c_func(i, s)

Описание:

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

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

Если Си-функция не требует подачи никаких аргументов, тогда ряд s должен быть пустым рядом {}.

Если в качестве аргумента вы подаёте величину, которая содержит дробную часть, в то время как Си-функция ожидает целочисленный тип Си, аргумент будет округлен в сторону нуля, т.е. 5.9 будет подано как 5, а -5.9 будет подано как -5.

Функция Си может входить в состав библиотеки .dll или .so, созданной транслятором с Euphoria на Си. В этом случае выдаваемая ею величина могла бы быть типа атом или ряд Euphoria. Но функции Си и функции машинного кода могут выдавать только целочисленные величины или, в более общем случае, атомы (числа с плавающей точкой по стандарту IEEE).

Пример:

atom user32, hwnd, ps, hdc
integer BeginPaint
-- открыть user32.dll - она содержит Си-функцию BeginPaint
user32 = open_dll("user32.dll")
-- Си-функция BeginPaint принимает аргументы типа C int и
-- типа C pointer, и выдаёт величину типа C int в качестве результата:
BeginPaint = define_c_func(user32, "BeginPaint",
{C_INT, C_POINTER}, C_INT)
-- вызвать BeginPaint, подавая hwnd и ps в качестве аргументов,
-- присвоить результат hdc:
hdc = c_func(BeginPaint, {hwnd, ps})

См. также:

c_proc, define_c_func, open_dll, platform_r.htm

c_proc

Платформа:

WIN32, Linux, FreeBSD

Синтаксис:

c_proc(i, s)

Описание:

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

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

Если Си-функция не требует подачи никаких аргументов, тогда ряд s должен быть пустым рядом {}.

Если в качестве аргумента вы подаёте величину, которая содержит дробную часть, в то время как Си-функция ожидает целочисленный тип Си, аргумент будет округлен в сторону нуля, т.е. 5.9 будет подано как 5, а -5.9 будет подано как -5.

Функция Си может входить в состав библиотеки .dll или .so, созданной транслятором с Euphoria на Си.

Пример:

atom user32, hwnd, rect
integer GetClientRect
-- открыть user32.dll - здесь содержится Си-функция GetClientRect
user32 = open_dll("user32.dll")
-- GetClientRect - это Си-функция типа VOID, у которой два аргумента - типа C int
-- и типа C pointer:
GetClientRect = define_c_proc(user32, "GetClientRect",
{C_INT, C_POINTER})
-- подать hwnd и rect в качестве аргументов
c_proc(GetClientRect, {hwnd, rect})

См. также:

c_func, call, define_c_proc, open_dll, platform_r.htm

call_func

Синтаксис:

x = call_func(i, s)

Описание:

Вызывает определенную программистом Euphoria-функцию с идентификатором (номером) подпрограммы i. Аргумент i должен быть разрешенным идентификатором (номером), выданным routine_id(). Аргумент s является рядом длины n, содержащим аргументы занумерованной функции, где n - число аргументов, требуемых функцией номер i. Переменная x будет содержать результат, выданный функцией номер i.

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

Если функция номер i не требует подачи никаких аргументов, тогда ряд s должен быть пустым рядом {}.

Пример программы:

democsort.ex

См. также:

call_proc, routine_id

call_proc

Синтаксис:

call_proc(i, s)

Описание:

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

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

Если процедура номер i не требует подачи никаких аргументов, тогда ряд s должен быть пустым рядом {}.

Пример:

global integer foo_id
procedure x()
call_proc(foo_id, {1, "Hello Worldn"})
end procedure
procedure foo(integer a, sequence s)
puts(a, s)
end procedure
foo_id = routine_id("foo")
x()

См. также:

call_func, routine_id

chdir

Синтаксис:

include file.e

i = chdir(s)

Описание:

Изменяет текущий каталог (директорию, фолдер, папку) по пути, который задан рядом s. Аргумент s должен содержать имя каталога, существующего на данной машине. В случае успешного изменения каталога chdir() выдаёт 1. Если перейти в заданный каталог не удалось, chdir() выдаёт 0.

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

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

Функция current_dir() выдаёт имя текущего каталога.

Под DOS32 и WIN32 текущий каталог является общим для всех программ и процессов, исполняемых в одной оболочке (т.е. под управлением одного и того же или единственного экземпляра интерпретатора команд ОС).

Под Linux/FreeBSD дочерние программы могут изменять текущий каталог для своих нужд, но эти изменения не будут относиться к текущему каталогу родительской программы.

Пример:

if chdir("c:euphoria") then
f = open("readme.doc", "r")
else
puts(1, "Ошибка: отсутствует каталог euphoria?n")
end if

См. также:

current_dir

check_break

Синтаксис:

include file.e

i = check_break()

Описание:

Выдаёт число нажатий сочетания клавиш control-c или control-Break, имевших место с момента последнего вызова check_break(), или с начала программы, если этот вызов первый.

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

Данная функция полезна, если в вашей программе была исполнена команда allow_break(0), которая запрещает прерывание вашей программы по нажатию сочетания клавиш control-c и control-Break. Вы можете использовать check_break(), чтобы выяснить, не нажимал ли всё-таки пользователь одно из этих аварийных сочетаний клавиш. Затем вы можете сделать всё то, что требуется для аккуратного и безошибочного завершения вашей программы без малейшего риска потери данных и повреждений файловой системы на диске.

В этих условиях ни control-c, ни control-Break не будут выданы как управляющие символы в операционную систему, если даже вы читаете состояние клавиатуры. Вы сможете только обнаружить, что нажатия состоялись, вызвав check_break().

Пример:

k = get_key()
if check_break() then
temp = graphics_mode(-1)
puts(1, "Программа завершается ...")
save_all_user_data()
abort(1)
end if

См. также:

allow_break, get_key

clear_screen

Синтаксис:

clear_screen()

Описание:

Очищает экран, заполняя его текущим фоновым цветом (этот цвет может быть также задан с помощью bk_color()) и устанавливая курсор в левый верхний угол экрана.

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

Процедура работает во всех текстовых и пиксельных режимах.

См. также:

bk_color, graphics_mode

close

Синтаксис:

close(fn)

Описание:

Закрывает файл или устройство, завершив вывод символов, если они ещё оставались в буфере к данному моменту.

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

Когда ваша программа заканчивается при нормальном её течении, все открытые файлы и устройства закрываются автоматически, если не были закрыты ранее с помощью команды close(fn).

См. также:

open, flush

command_line

Синтаксис:

s = command_line()

Описание:

Выдаёт ряд, состоящий из строк, в котором каждая строка является словом, введённым в командную строку, с которой была запущена ваша программа. В первом слове будет путь к интерпретатору Euphoria ex.exe, exw.exe или exu, или к вашему связанному исполняемому файлу. В следующем слове будет или имя вашего Euphoria .ex файла, или (опять же) путь к вашему связанному исполняемому файлу. Затем будут идти все те дополнительные слова, которые были введены вами. Вы можете использовать эти слова в вашей программе, например, задавая тот или иной режим её работы. Серии слов можно забирать в кавычки, чтобы тем самым превратить серию слов в единственный аргумент.

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

Собственно интерпретаторы Euphoria не используют никаких аргументов командной строки. Но вы можете использовать любые аргументы по своему усмотрению для своих собственных программ.

Если вы преобразовали вашу программу к виду .exe с помощью биндера или транслятора, вы найдете, что аргументы командной строки остались теми же самыми, за исключением первых двух, хотя ваш пользователь уже не вводит "ex" в командной строке (см. примеры ниже).

Пример 1:

-- Пользователь вводит: ex myprog myfile.dat 12345 "the end"
cmd = command_line()
-- cmd будет равно:
{"C:EUPHORIABINEX.EXE",
"myprog",
"myfile.dat",
"12345",
"the end"}

Пример 2:

-- Ваша программа окутана, её имя "myprog.exe",
-- и помещена в каталог c:myfiles
-- Пользователь вводит: myprog myfile.dat 12345 "the end"
cmd = command_line()
-- cmd будет равно:
{"C:MYFILESMYPROG.EXE",
"C:MYFILESMYPROG.EXE", -- заполнитель места
"myfile.dat",
"12345",
"the end"
}
-- Заметьте, что все аргументы остались теми же, что и в примере 1,
-- исключая первые два. Второй аргумент теперь повторяет первый,
-- и служит просто для того, чтобы сохранить постоянной нумерацию
-- остальных аргументов, независимо от того, имеет ваша программа
-- форму .exe, или нет.

См. также:

getenv

compare

Синтаксис:

i = compare(x1, x2)

Описание:

Выдаёт 0, если объекты x1 и x2 идентичны, 1, если x1 больше чем x2, -1, если x1 меньше чем x2. Считается, что атомы меньше рядов. Ряды сравниваются поэлементно, начиная с первого элемента, до момента, пока не найдено первое различие.

Пример 1:

x = compare({1,2,{3,{4}},5}, {2-1,1+1,{3,{4}},6-1})
-- идентичны, x равно 0

Пример 2:

if compare("ABC", "ABCD") < 0 then -- -1
-- результатом будет истина: ряд ABC считается "меньшим", так как он короче
end if

Пример 3:

x = compare({12345, 99999, -1, 700, 2},
{12345, 99999, -1, 699, 3, 0})
-- x будет равно 1, так как 700 699

Пример 4:

x = compare('a', "a")
-- x будет равно -1, так как 'a' является атомом,
-- в то время как "a" является рядом длины 1

См. также:

equal, операции сравнения, операции на рядах

cos

Синтаксис:

x2 = cos(x1)

Описание:

Вычисляет и выдаёт косинус x1, где x1 выражено в радианах.

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

Данная функция применима к атомам или ко всем элементам ряда.

Пример:

x = cos({.5, .6, .7})
-- x равно {0.8775826, 0.8253356, 0.7648422}

См. также:

sin, tan, log, sqrt

crash_file

Синтаксис:

include machine.e

crash_file(s)

Описание:

Задаёт представленное в виде ряда s имя файла, предназначенного для вывода диагностической информации, когда Euphoria вынуждена аварийно остановить вашу программу из-за ошибки, обнаруженной во время компиляции или во время работы.

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

Обычно Euphoria печатает диагностическое сообщение вроде "syntax error" или "divide by zero" на экране, одновременно выводя отладочную информацию в файл ex.err, который всегда располагается в текущем каталоге.

Вызывая crash_file(), вы можете управлять именами файла и каталога, в которых будет записываться отладочная информация.

Ряд s может быть пустым, т.е. "". В этом случае диагностическая или отладочная информация не будет выводиться ни на экран, ни в файл. Ряд s может также иметь форму "NUL" или "/dev/null", в этом случае диагностическая информация будет выводиться на экран, но в файл ex.err ничего не будет записано.

Вы можете вызывать crash_file() столько раз, сколько это нужно, в различных частях вашей программы. В случае таких многократных вызовов будет использоваться тот файл, который был задан в последней команде crash_file(), стоящей перед точкой возникновения ошибки .

Пример:

crash_file("tmpmybug")

См. также:

abort, crash_message, crash_routine, отладка и профилирование

crash_message

Синтаксис:

include machine.e

crash_message(s)

Описание:

Задаёт сообщение, представленное в виде ряда s, которое будет выведено на экран в случае, если Euphoria аварийно остановит вашу программу из-за ошибки, обнаруженной во время работы.

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

Обычно Euphoria печатает диагностическое сообщение на экране, например, "subscript out of bounds" (индекс вне границ) или "divide by zero" (деление на ноль), сопровождая его распечаткой отладочной информации в файле ex.err. Эти сообщения об ошибках будут малопонятны для тех ваших пользователей, которые сами не являются программистами Euphoria. Но вызывая crash_message(), вы сможете управлять содержимым сообщений, появляющихся на экране, чтобы наиболее полно учесть уровень понимания аварийной ситуации пользователями вашей программы. При этом вся отладочная информация будет ещё и распечатываться в файле ex.err, так что вы не потеряете никаких данных об ошибке, пользуясь этой дополнительной возможностью и подправляя стандартные сообщения.

Ряд s может содержать 'n', символы новой строки, поэтому ваше сообщение легко сделать исчерпывающе подробным, причем на вашем родном языке, а не на английском, на котором Euphoria выводит свои собственные сообщения. Перед выводом вашего сообщения Euphoria переключит экран в текстовый режим и начнет печать с верхней строки чистого экрана.

Вы можете вызывать crash_message() столько раз из различных участков вашей программы, сколько это необходимо. Будет выведено только одно сообщение, то, которое задано последним перед точкой возникновения ошибки.

Пример:

crash_message("Произошла неизвестная ранее ошибка!n" &
"Свяжитесь с [email protected]" &
"Не удаляйте файл "ex.err".n")

См. также:

abort, crash_file, crash_routine, отладка и профилирование

crash_routine

Синтаксис:

include machine.e

crash_routine(i)

Описание:

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

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

Определяя аварийные функции, вы даёте своей программе шанс отреагировать на фатальные ошибки (такие, например, как индекс вне границ), возникающие во время её работы, наиболее безопасным для ваших данных способом. Вы можете записать некоторые критичные данные на диск. Вы можете проинформировать пользователя о том, что случилось и что он должен в первую очередь сделать. Вы можете также записать ключевую отладочную информацию. Фактически, когда ваша аварийная функция вызвана, файл ex.err уже будет записан. Ваша функция может перезаписать ex.err ещё где-то, или даже открыть его и извлечь из него необходимую информацию, например, сообщение об ошибке.

Команда crash_routine() может использоваться с интерпретатором или транслятором. Транслированный код не выполняет широкую проверку ошибок во время работы программы и не обеспечивает полную распечатку в ex.err, но исключения машинного уровня фиксируются, и crash_routine() дает вам превосходную возможность записать некоторые переменные на диск для использования при дальнейшей отладке.

Разработчику библиотеки может понадобиться вызов crash_routine() в библиотеке. Это позволит более упорядоченно обращаться с данными, закрывая файлы, отпирая запертые файлы, высвобождая ресурсы и т.п. Но разработчик главной программы может иметь и свои собственные crash_routine(). И все аварийные функции будут отработаны Euphoria, если первая вызванная (последняя назначенная) и все последующие выдадут 0.

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

Если во время исполнения аварийной функции случится другая ошибка, снова вызывается распечатка отладочной информации, но имя файла в этом случае будет уже ex_crash.err, а не ex.err. С этого момента запрещаются любые новые вызовы аврийных функций, а вы остаётесь наедине с ex.err и ex_crash.err, чтобы с ними в руках попытаться найти причину всех несчастий.

Пример:

function crash(object x)
-- в случае пожара ...
-- (под Linux) отправить сообщение e-mail, содержащее файл ex.err
system("mail -s "crash!" [email protected] < ex.err > /dev/null", 2)
return 0
end function
crash_routine(routine_id("crash"))

См. также:

abort, crash_file, crash_message, отладка и профилирование

current_dir

Синтаксис:

include file.e

s = current_dir()

Описание:

Выдаёт имя текущего рабочего каталога (директории, папки, фолдера).

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

После имени текущего каталога не будет ни косой черты, ни обратной косой черты, за исключением случая под DOS/Windows, в корневом каталоге диска, где вы получите, например, C:

Пример:

sequence s
s = current_dir()
-- s будет равно "C:EUPHORIADOC", если вы находитесь в этом каталоге

См. также:

dir, chdir, getenv

cursor

Платформа:

WIN32, DOS32

Синтаксис:

include graphics.e

cursor(i)

Описание:

Задаёт форму курсора. Библиотека graphics.e содержит глобальные константы:

global constant NO_CURSOR = #2000,
UNDERLINE_CURSOR = #0607,
THICK_UNDERLINE_CURSOR = #0507,
HALF_BLOCK_CURSOR = #0407,
BLOCK_CURSOR = #0007

Вторая и четвертая шестнадцатиричные цифры (слева) дают номера верхнего и нижнего рядов пикселов в изображении курсора. От первой цифры зависит, будет курсор видимым или нет. Например, #0407 включает с 4-го по 7-ой ряд пикселов.

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

В пиксельных экранных режимах курсор не отображается, только в текстовых.

Пример:

cursor(BLOCK_CURSOR)

См. также:

graphics_mode, text_rows

custom_sort

Синтаксис:

include sort.e

s2 = custom_sort(i, s1)

Описание:

Сортирует элементы ряда s1, используя заданную сравнивающую функцию с номером (идентификатором) i. Выдаёт отсортированный ряд.

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

Заданная вами заказная сравнивающая функция должна быть функцией двух аргументов наподобие Euphoria-функции compare(). Она должна сравнивать два объекта и выдавать -1, 0 или +1.

Пример программы:

democsort.ex

См. также:

sort, compare, routine_id

date

Синтаксис:

s = date()

Описание:

Выдаёт ряд со следующей информацией:

{год, -- начиная с 1900
месяц, -- январь = 1
день, -- день месяца, начиная с 1
час, -- от 0 до 23
минута, -- от 0 до 59
секунда, -- от 0 до 59
день недели, -- воскресенье = 1

день года} -- 1 января = 1

Пример:

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

См. также:

euphoriademocallmach.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.

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

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

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

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

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

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

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

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

Пример:

atom user32
integer ShowWindow
-- Открываем системную библиотеку user32.dll - в ней находится Си-функция ShowWindow.
user32 = open_dll("user32.dll")
-- Си-функция требует 2-х аргументов, оба типа C int.
ShowWindow = define_c_proc(user32, "ShowWindow", {C_INT, C_INT})
-- Если бы ShowWindow работала по правилам cdecl,
-- мы записали бы здесь "+ShowWindow"
if ShowWindow = -1 then
puts(1, "ShowWindow не найдена!n")
end if

См. также:

c_proc, define_c_func, c_func, open_dll, platform_r.htm

define_c_var

Платформа:

WIN32, Linux, FreeBSD

Синтаксис:

include dll.e

a1 = define_c_var(a2, s)

Описание:

Выдаёт адрес переменной Си, загруженной в память. Аргумент a2 является адресом общей библиотеки .so Linux, FreeBSD или .dll Windows, выданным функцией open_dll(). Ряд s задает имя глобальной переменной Си, определенной внутри системной библиотеки. В переменной a1 будет содержаться значение адреса переменной s в памяти.

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

Как только вы получили адрес переменной Си, и если вы знаете её тип, вы можете далее использовать подпрограммы peek() и poke(), чтобы считывать или записывать в памяти величину этой переменной.

Пример программы:

euphoria/demo/linux/mylib.exu

См. также:

c_proc, define_c_func, c_func, open_dll, platform_r.htm

dir

Синтаксис:

include file.e

x = dir(st)

Описание:

Выдаёт информацию о каталоге или о файле с именем st. Если такой каталог или файл не существует, выдаёт -1. Под Windows и DOS st может содержать символы догадок * и ?, что позволяет получать данные о нескольких файлах с похожими именами.

Выдаваемая информация похожа на ту, которую вы получаете по команде DIR под DOS. Ряд, формируемый функцией, содержит вложенные ряды (записи), каждый из которых описывает один файл или подкаталог.

Если в st задано имя каталога (директории, папки, фолдера), вы можете получить записи для "." и "..", точно так же, как и по команде DIR под DOS. Если же в st задано имя файла, тогда x будет иметь только одну запись, т.е. length(x) будет равна 1. Если в st содержатся символы догадок (шаблоны), вы можете получить многочисленные записи.

Каждая запись содержит имя, атрибуты файла и его размер, а также год, месяц, день, час, минуту и секунду последнего изменения. Вы можете обращаться к элементам записи с помощью следующих констант, определенных в библиотеке file.e:

global constant D_NAME = 1, -- имя
D_ATTRIBUTES = 2, -- атрибуты
D_SIZE = 3, -- размер
D_YEAR = 4, -- год
D_MONTH = 5, -- месяц
D_DAY = 6, -- день
D_HOUR = 7, -- час
D_MINUTE = 8, -- минута

D_SECOND = 9 -- секунда

Элемент атрибутов является строковым рядом, содержащим символы, выбранные из следующего перечня:

'd' -- каталог
'r' -- файл только для чтения
'h' -- скрытый файл
's' -- системный файл
'v' -- метка тома

'a' -- файл, подлежащий архивированию

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

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

Каталог высшего уровня, корневой, т.е. c:, не содержит записей "." или "..".

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

На платформе WIN32 в st могут содержаться длинные имена файлов или каталогов в любом месте полного пути.

На платформах Linux/FreeBSD в настоящее время доступен только атрибут 'd'.

DOS32: Имя файла, выдаваемое в элементе D_NAME, будет стандартным DOS-именем формата 8.3 (посетите Web-страницу Архива файлов, если вас интересует лучшее решение).

WIN32: Имя файла, выдаваемое в элементе D_NAME, будет длинным именем.

Пример:

d = dir(current_dir())
-- ряд d мог бы быть, например, равным:
{
{".", "d", 0 1994, 1, 18, 9, 30, 02},
{"..", "d", 0 1994, 1, 18, 9, 20, 14},
{"fred", "ra", 2350, 1994, 1, 22, 17, 22, 40},
{"sub", "d", 0, 1993, 9, 20, 8, 50, 12}
}
-- тогда d[3][D_NAME] было бы "fred"

Пример программы:

binsearch.ex

См. также:

wildcard_file, current_dir, open

display_image

Платформа:

DOS32

Синтаксис:

include image.e

display_image(s1, s2)

Описание:

Выводит в точке s1 на пиксельном экране 2-мерный ряд пикселов, описание которых содержится в s2. Аргумент s1 - двухэлементный ряд вида {x, y}. Аргумент s2 содержит ряды, каждый из которых представляет горизонтальную строчку значений цветов пикселов, которые необходимо включить на экране. Первый пиксел первого ряда расположен в точке s1. Это верхний левый пиксел. Все остальные пикселы расположены правее или ниже этого первого.

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

Ряд s2 может быть результатом предшествовавшего вызова save_image() или вызова read_bitmap(), или тем, что секундой ранее вы рисовали в своем воображении.

Ряды (строчки) изображения могут быть разной длины.

Пример:

display_image({20,30}, {{7,5,9,4,8},
{2,4,1,2},
{1,0,1,0,4,6,1},
{5,5,5,5,5,5}})
-- Процедура выведет на экран небольшое изображение, состоящее
-- из 4-х горизонтальных рядов пикселов. Первый пиксел (цвет номер 7)
-- будет включен в точке {20,30}. Верхний ряд состоит из 5 пикселов.
-- Последний (нижний) ряд состоит из 6 пикселов цвета номер 5
-- и заканчивается в точке {25,33}.

Пример программы:

demodos32bitmap.ex

См. также:

save_image, read_bitmap, display_text_image

display_text_image

Синтаксис:

include image.e

display_text_image(s1, s2)

Описание:

Выводит на экран 2-мерный ряд символов c заданными атрибутами, начиная с заданной экранной позиции. Аргумент s1 является двухэлементным рядом, содержащим координаты начальной экранной позиции - строка s1[1], колонка s1[2]. Аргумент s2 состоит из вложенных рядов, каждый из которых является строкой выводимых символов и их атрибутов. Верхний левый символ выводится в позиции s1. Другие символы появляются правее и ниже этой позиции. Атрибут следует за символом и своим кодом указывает цвет символа и цвет фона на котором символ должен быть отображён. Под DOS32 атрибут представляет собой сумму номера цвета и умноженного на 16 номера цвета фона.

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

Ряд s2 обычно будет результатом предшествующего вызова функции save_text_image(), хотя вы можете сконструировать этот ряд и сами.

Данная процедура работает только в текстовых экранных режимах.

Пара подпрограмм save_text_image() и display_text_image() пригодится вам для организации в текстовом режиме графического пользовательского интерфейса с всплывающими диалогами и выпадающими меню, которые появляются и исчезают без потери того, что было на экране до них.

Строки текстового изображения могут иметь разную длину.

Пример:

clear_screen()
display_text_image({1,1}, {{'A', WHITE, 'B', GREEN},
{'C', RED+16*WHITE},
{'D', BLUE}})
-- начиная с верхнего левого угла экрана, выводится:
AB
C
D
-- 'A' - белого цвета на чёрном (0) фоне,
-- 'B' - зелёного цвета на чёрном фоне,
-- 'C' - красного цвета на белом фоне и
-- 'D' - синего цвета на чёрном фоне.

См. также:

save_text_image, display_image, put_screen_char

dos_interrupt

Платформа:

DOS32

Синтаксис:

include machine.e
s2 = dos_interrupt(i, s1)

Описание:

Вызывает программное прерывание DOS номер i. Аргумент s1 является 10-элементным рядом 16-битных значений, заносимых в регистры процессора перед входом в процедуру прерывания. Ряд s2 аналогичен 10-элементному ряду s1, в нем будут содержаться значения регистров после выхода из процедуры прерывания. В файле machine.e имеется следующее объявление констант, из которого ясно расположение значений регистров во входном и выходном рядах s1 и s2:

global constant REG_DI = 1,
REG_SI = 2,
REG_BP = 3,
REG_BX = 4,
REG_DX = 5,
REG_CX = 6,
REG_AX = 7,
REG_FLAGS = 8,
REG_ES = 9,
REG_DS = 10

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

Значения регистров, выдаваемые в s2, всегда являются положительными целыми числами между 0 и #FFFF (65535).

Значения флагов в s1[REG_FLAGS] на входе игнорируются. На выходе младший значащий бит в s2[REG_FLAGS] соответствует флагу состояния, который обычно указывает на неудачу, если он установлен в 1.

Некоторые прерывания требуют, чтобы вы указывали адреса участков памяти. Эти адреса должны относиться к стандартной (нижней) памяти. Вы можете подготовить/освободить нижнюю память с помощью функций allocate_low() и free_low().

С программными прерываниями DOS вы имеете доступ ко всему широкому кругу специализированных операций, любых, от форматирования вашего флоппи-диска до перезагрузки компьютера. Документацию по этим прерываниям можно найти в книге Питера Нортона "Библия программиста PC", или в файле "Список прерываний" на странице Web Ральфа Брауна по адресу:

http://www.cs.cmu.edu/afs/cs.cmu.edu/user/ralf/pub/WWW/files.html

Пример:

sequence registers
registers = repeat(0, 10) -- установка значений регистров не требуется
-- вызывается прерывание номер 5 DOS: Print Screen - Печатать Экран
registers = dos_interrupt(#5, registers)

Пример программы:

demodos32dosint.ex

См. также:

allocate_low, free_low

draw_line

Платформа:

DOS32

Синтаксис:

include graphics.e

draw_line(i, s)

Описание:

Чертит на экране в пиксельном режиме линию, соединяющую две или более точек с координатами, заданными в s, используя цвет номер i.

Пример:

draw_line(WHITE, {{100, 100}, {200, 200}, {900, 700}})
-- Белой линией будут соединены три точки
-- от {100, 100} до {200, 200}
-- и от {200, 200} до {900, 700}.

См. также:

polygon, ellipse, pixel

...

Оглавление книги


Генерация: 0.077. Запросов К БД/Cache: 0 / 1
поделиться
Вверх Вниз