書式: | call(a) |
解説: | 開始アドレスaよりマシン語ルーチンを呼び出します。このルーチンを実行するさいRETインストラクション #C3で制御をEuphroia返す必要があります。また、ルーチンは使用前に使用対象レジスタを退避して使用後に復元する必要があります。 |
注釈: | メモリーブロックにルーチンを割り当てることができマシン語コードのバイトを挿入することができます。その他のメモリーブロックにマシン語コードが操作できるデータとパラメータを挿入することがあります。これらのブロックのアドレスにマシン語コードの挿入ができます。 |
プログラム例: | demo\callmach.ex |
関連事項: | allocate, free, peek, poke, poke4, c_proc, define_c_proc |
動作環境: | WIN32, Linux, FreeBSD |
書式: | include dll.e a = call_back(i) or a = call_back({i1, i}) |
解説: | Eupphoriaルーチンのルーチンid i のマシンアドレスを取得します。このアドレスはWindowsまたはWindows .dllやLinux/FreeBSD共有ライブラリ(.so)の外部C言語ルーチンを32bit "コールバック"アドレスとみなしてEuphoriaのルーチンから呼び出します。Windowsでは、i1にルーチンを呼び出ぶために使用するC言語呼び出し規約を指定することができます。i1が'+'ならば、ルーチンはcdecl呼び出し規約で動作します。規定値ではstdcall規約で動作します。LinuxおよびFreeBSDではi1を指定しない最初の形式を使用する必要があり、それは標準規約を使用して呼び出します。 |
注釈: | コールバック関数は好きなように設定できますが、すべてのEuphoria関数(または型)に対しての設定は0から9の整数値で構成される引数を渡す必要があります。もし、ルーチンが値を返さない場合は(手続きである必要があります)、0が返りますが(大抵は)、呼び出したC言語ルーチンの返値を無視することができます。
ルーチンを呼ぶとき、すべての引数値は符号なし(整数)の32bit値です。強度の引数検査を強要したくない場合は、ルーチンの各引数をアトムで宣言する必要があります。ルーチンは32bit整数値を返す必要があります。 Linux/FreeBSDではコールバックアドレスをsignal()関数の例外ハンドラとしてEuphoriaルーチンを指定するために使用できます。例えば、SIGTERMシグナルを捕えて、正規の手順で終了処理が行えます。一部のウェブサーバーでは膨大なCPU時間を使用したCGIプロセスにSIGTERMを送信します。 浮動小数点数の値を返すcdecl規約のコールバックルーチンをexwで使用する場合は動作しません。理由としてWatcom Cコンパイラが(exwをビルドするために使用される)cdecl規約の浮動小数点の返値を一般的ではない方法で扱うためです。 |
プログラム例: | demo\win32\window.exw, demo\linux\qsort.exu |
関連事項: | routine_id, platform.doc |
動作環境: | WIN32, Linux, FreeBSD |
書式: | x = c_func(i, s) |
解説: | C言語関数、マシン語関数、トランスレート/コンパイルされたEuphoria関数のいずれかをルーチンid iで呼び出します。i は define_c_func() によって返される有効なルーチンidである必要があります。sは長さnのシーケンスの引数値で、n個の引数が関数によって要求されます。x には関数の処理結果が返されます。 |
注釈: | もし、関数が引数を一切もたない場合は s に {}を指定する必要があります。
もし、小数の一部を含む値を引数として渡すとき、C言語関数はC言語整数型とみなして、引数を0で丸め込みます。すなわち、5.9を渡すと5、-5.9を渡すと-5になりますので注意が必要です。 関数はEuphoria→C言語トランスレータによって.dllまたは.soを作成することができます。この場合、Euphoriaのアトムまたはシーケンスを返すことができます。C言語関数とマシン語関数は、一般的な整数またはアトム(IEEE浮動点小数)のみ返すことができます。 |
用例: | |
atom user32, hwnd, ps, hdc integer BeginPaint -- user32.dllを開きます。 - これにはC言語関数 BeginPaint があります。 user32 = open_dll("user32.dll") -- C言語関数BeginPaintには引数としてC言語int型と、 -- C言語ポインタ型があり、C言語int型で結果を返します。 BeginPaint = define_c_func(user32, "BeginPaint", {C_INT, C_POINTER}, C_INT) -- 引数としてhwndとpsを与えて、BeginPaintに呼び出すと -- hdcには結果が代入されます: hdc = c_func(BeginPaint, {hwnd, ps}) | |
関連事項: | c_proc, define_c_func, open_dll, platform.doc |
動作環境: | WIN32, Linux, FreeBSD |
書式: | c_proc(i, s) |
解説: | C言語関数、マシン語関数のいずれかをルーチンid iで呼び出します。i は define_c_proc() によって返される有効なルーチンidである必要があります。sは長さnのシーケンスの引数値で、n個の引数が関数によって要求されます。 |
注釈: | もし、関数が引数を一切もたない場合は s に {}を指定する必要があります。
もし、小数の一部を含む値を引数として渡すとき、C言語関数はC言語整数型とみなして、引数を0で丸め込みます。すなわち、5.9を渡すと5、-5.9を渡すと-5になりますので注意が必要です。 関数はEuphoria→C言語トランスレータによって.dllまたは.soを作成することができます。 |
用例: | |
atom user32, hwnd, rect integer GetClientRect -- user32.dllを開きます。 - これにはC言語関数 GetClientRect があります user32 = open_dll("user32.dll") -- GetClientRectはVOID型のC言語関数であり、引数としてC言語int型と -- C言語ポインタ型があります: 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.doc |
書式: | x = call_func(i, s) |
解説: | ユーザ定義済みEuphoria関数をルーチンID iを使用して呼び出します。i は routine_id()によって返された有効なルーチンidである必要があります。sは長さnのシーケンスの引数値で、n個の引数が関数によって要求されます。x には関数 i の処理結果が返されます。 |
注釈: | もし、関数iが引数を一切もたない場合はsに {}を指定する必要があります。 |
プログラム例: | demo\csort.ex |
関連事項: | call_proc, routine_id |
書式: | call_proc(i, s) |
解説: | ユーザ定義したEuphoria手続きをルーチンID iを使用して呼び出します。i は routine_id()によって返された有効なルーチンidである必要があります。sは長さnのシーケンスの引数値で、n個の引数が手続きによって要求されます。 |
注釈: | もし、手続きiが引数を一切もたない場合はsに {}を指定する必要があります。 |
用例: | |
global integer foo_id procedure x() call_proc(foo_id, {1, "Hello World\n"}) end procedure procedure foo(integer a, sequence s) puts(a, s) end procedure foo_id = routine_id("foo") x() | |
関連事項: | call_func, routine_id |
書式: | include file.e i = chdir(s) |
解説: | パスであるシーケンス sを与えてカレントディレクトリを設定します。sはシステムに存在するディレクトリ名である必要があります。chdir()は処理が成功したときはiに1を返します。 chdir()は処理が失敗したときはiに0を返します。 |
注釈: | カレントディレクトリを設定することにより、そのファイル名を使用しているディレクトリのファイルを参照することができます。
current_dir()関数はカレントディレクトリ名を返します。 DOS32およびWIN32ではカレントディレクトリはすべてのプロセスは1つのシェル上で動作するグローバルな共有資産です。Linux/FreeBSDでは、サブプロセスはカレントディレクトとそれ自身を変更することができますが、これは親プロセスのカレントディレクトリに影響を及ぼしません。 |
用例: | |
if chdir("c:\\euphoria") then f = open("readme.doc", "r") else puts(1, "Error: No euphoria directory?\n") end if | |
関連事項: | current_dir |
書式: | include file.e i = check_break() |
解説: | 最後にcheck_break()を呼び出してから次のcheck_break()までにCtrl+CまたはCtrl+Breakを押した回数を返します。これが最初であればプログラム開始直後だということを返します。 |
注釈: | Ctrl+CまたはCtrl+Breakによるプログラムの強制終了を禁止するためにallow_break(0)を呼び出した後に好都合です。check_break()はユーザがこれらのキーのうちひとつを押したかどうか検出するために使用できます。これらのキーを検出後にプログラムを正規の手順で終了するための処理が必要かもしれません。
キーボードからはCtrl+CまたはCtrl+Breakは入力文字として返されません。これらはcheck_break()のみ検出できます。 |
用例: | |
k = get_key() if check_break() then temp = graphics_mode(-1) puts(1, "Shutting down...") save_all_user_data() abort(1) end if | |
関連事項: | allow_break, get_key |
書式: | clear_screen() |
解説: | 現在の背景色でスクリーンを消去します(bk_color()で背景色を設定できます)。 |
注釈: | これはテキストおよびピクセルグラフィックスの全てのモードで動作します。 |
関連事項: | bk_color, graphics_mode |
書式: | close(fn) |
解説: | ファイルまたはデバイスを閉じてバッファにある全ての内容をフラッシュして出力します。 |
注釈: | プログラム終了時に開いているファイルは自動的に閉じられます。 |
関連事項: | open, flush |
書式: | s = command_line() |
解説: | プログラム開始時に取得したコマンドライン文字列を文字列シーケンスとして返します。最初の文字列はEuphoriaのex.exe, exw.exe, exwc.exeまたはeuiか、バインド化処理されたプログラムのいずれかの実行ファイルのパスです。次の文字列はEuphoriaインタプリタで使用するメインプログラムまたはバインド化処理されたプログラムのいずれかの実行可能なファイルのパスまたは名前です。これらの追加文字列はユーザによって入力が行われます。これらの文字列はプログラムで使用することができます。 |
注釈: | Euphoriaインタプリタはコマンドラインオプションを使用しません。どのようなオプションであってもプログラムでは自由に使用してかまいません。
利用者は単一の引数文字列に対してクォートで括ることができます。 もしプログラムを実行ファイルへ変換するならば、バインディングか、トランスレータでC言語ソースに変換するとユーザがコマンドラインでEuphoriaインタプリタのコマンド名(exなど)を入力しない場合であっても、コマンドライン引数の最初の2つ以外は同一です(後述の用例を参照してください)。 |
用例1: | |
-- 利用者が次のように入力したとします: ex myprog myfile.dat 12345 "the end" cmd = command_line() -- cmdは次のようになります: {"C:\EUPHORIA\BIN\EX.EXE", "myprog", "myfile.dat", "12345", "the end"} | |
用例2: | |
-- プログラムは"myprog.exe"の名称でバインド化処理がされており、 -- c:\myfilesディレクトリに格納されているとします。 -- 利用者が次のように入力したとします: myprog myfile.dat 12345 "the end" cmd = command_line() -- cmdは次のようになります: {"C:\MYFILES\MYPROG.EXE", "C:\MYFILES\MYPROG.EXE", -- プレースホルダー(位置情報指示子) "myfile.dat", "12345", "the end" } -- 注意事項として全引数は最初の2つを除き同一です。 -- プログラムがバインド化処理またはトランスレータで -- .exe化されるかに関わらず第2引数以降は -- 常に最初と同一であり以降の引数の番号を -- 同一にするために挿入されています。 | |
関連事項: | getenv |
書式: | i = compare(x1, x2) |
解説: | オブジェクトx1およびx2が同じであれば0を返し、x1がx2より大きいか少なければ-1を返します。アトムはシーケンスより小さいと判断されます。違いが見つかるまでシーケンスは最初の要素から"アルファベット順"に比較されます。 |
用例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}) -- 700 > 699であるためxは1になります。 | |
用例4: | |
x = compare('a', "a") -- 'a' はアトムであり、一方の"a"は -- シーケンスであるためxは-1になります。 | |
関連事項: | equal, 関係演算子, シーケンスの演算 |
書式: | x2 = cos(x1) |
解説: | x1のコサインを返します。x1はラジアンです。 |
注釈: | この関数はアトムまたはシーケンスの全ての要素に適用されることがあります。 |
用例: | |
x = cos({.5, .6, .7}) -- x は {0.8775826, 0.8253356, 0.7648422} | |
関連事項: | sin, tan, log, sqrt |
書式: | include machine.e crash_file(s) |
解説: | Euphoriaはコンパイル時または実行時にエラーが発生してプログラムを停止するときにエラー診断情報を保持するファイルsを指定します。 |
注釈: | 通常Euphoriaは"構文エラー"または"0除算エラー"といった診断メッセージをスクリーンに出力し、デバッグ情報をダンプ結果として現在ディレクトリにex.errを作成します。crash_file()を呼び出すことによりデバッグ情報を書き出すディレクトリとファイル名を制御できます。
たとえば""、といったようにsが空かもしれません。この場合は診断またはデバッグ情報がファイルに出力されません。sが"NUL"または"/dev/null"かもしれないときは、診断情報はスクリーンに出力されますが、ex.errの情報は破棄されます。 プログラムのどこでも好きなときに何度でもcrash_file()を呼び出すことができます。ファイル指定は最後にcrash_file()が呼び出されたものを使用します。 |
用例: | |
crash_file("\\tmp\\mybug") | |
関連事項: | abort, crash_message, crash_routine, デバッグとプロファイル |
書式: | include machine.e crash_message(s) |
解説: | Euphoriaがコンパイル時または実行時にプログラムを停止しなければならないときに表示する文字列sを指定します。 |
注釈: | 通常Euphoriaは"添字範囲外"や"0除算"といった診断メッセージをスクリーンに出力してデバッグ情報のダンプをex.errに出力します。これらのエラーメッセージはユーザがEuphoriaプログラマではないときは意味を持ちません。crash_message()を呼び出すことにより、スクリーンに表示されるメッセージを制御することができます。また、デバッグ情報はex.errに保存されています。こうすることにより必要な情報を少しも失うことはありません。
sには改行文字が'\n'含まれているときがありメッセージを数行に渡りスクリーン上に表示することができます。Euphoriaはメッセージを出力する前にテキストモードスクリーンを消去して上部にカーソルを移動します。 プログラムのどこでも好きなときに何度でもcrash_message()を呼び出すことができます。メッセージ指定は最後にcrash_message()が呼び出されたものを表示します。 |
用例: | |
crash_message("An unexpected error has occurred!\n" & "Please contact john_doe@whoops.com\n" & "Do not delete the file \"ex.err\".\n") | |
関連事項: | abort, crash_file, crash_routine, デバッグとプロファイル |
書式: | include machine.e crash_routine(i) |
解説: | ランタイムエラーが検出されたときとプログラムが強制終了されなければならないときにEuphoriaに呼び出してほしい関数のルーチンIDを渡すことができます。関数の引数には型オブジェクトを一つ渡す必要があります。現在のところ関数に渡されるオブジェクトは常に0です。Euphoriaの将来のリリースでは、より意味のある値を渡すことができるようになるかもしれません。どこでも好きなときに何度でも違うルーチンidを指定してcrash_routine()を呼び出してことができます。クラッシュが起きたとき、最初に最近指定されたクラッシュルーチンを呼び出してEuphoriaは指定された初期動作に戻します。通常各ルーチンは0を返す必要があります。ルーチンが非0の値を返すならば、連鎖的な呼び出しは即時終了します。 |
注釈: | クラッシュルーチンを指定することにより、より優雅な方法でプログラムの致命的なランタイムエラー(例えば添字の範囲外)を扱えるようになります。これによりディスクにいくつかの重要なデータ保存することができます。また、ユーザになにが発生したことか通知することもできます。さらに問題解決の鍵となるデバッグ情報も保存できます。実際にクラッシュルーチンが呼ばれるときにex.errが出力されます。クラッシュルーチンはエラーメッセージなどが含まれたex.errを何処かに保存することができ、それを開いて情報を得ることができます。
crash_routine()はインタプリタまたはトランスレータで使用できます。トランスレートされたコードは大部分のランタイムエラーを検出せず、完全なex.errのダンプを提供しません。しかし、マシンレベルの例外は検出でき、クラッシュルーチンはデバッグのために多少の変数の値をディスクに保存するすばらしい機会を提供します。 ライブラリ開発者はライブラリのためにクラッシュルーチンを指定したいときがあるかもしれません。それはファイルをアンロックして閉じる、リソースなどを開放することにより準備ができます。メインプログラム開発者はプログラム自身にクラッシュルーチンを持たせることができます。最初に呼ばれた(最後に指定されたもの)ものが非0を返さない限り両方のルーチンともEuphoriaによって呼ばれます。 クラッシュルーチンはクラッシュが発生した地点で実行を再開することはできませんが、ほかに何かするための制限はありません。また、復帰する必要はありません。これによりグローバル変数を再度初期化することができ、効率的にプログラムを再開することができます。 クラッシュルーチン動作中に別のエラーが発生したとき、新しくエラーダンプが生成されますがファイル名はex.errではなくex_crash.errになります。この時点でクラッシュルーチンを呼び出すことは許可されていません。なにが起こったかを完全理解するためにex.errとex_crash.errを調べる必要があります。 |
用例: | |
function crash(object x) -- クラッシュ発生... -- (Linuxでは) ex.errを含むメールを送信する。 system("mail -s \"crash!\" myname@xxx.com < ex.err > /dev/null", 2) return 0 end function crash_routine(routine_id("crash")) | |
関連事項: | abort, crash_file, crash_message, デバッグとプロファイル |
書式: | include file.e s = current_dir() |
解説: | 現在の作業ディレクトリ名を返します。 |
注釈: | スラッシュまたはバックスラッシュがカレントディレクトリの末尾にないとき、DOS/Windowsでは先頭がドライブとなります。すなわちC:\といったルートディレクトリが該当します。 |
用例: | |
sequence s s = current_dir() -- 現在のディレクトリが "C:\EUPHORIA\DOC" ならば、これをsに返します。 | |
関連事項: | dir, chdir, getenv |
動作環境: | 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 | |
最初の桁はカーソルの表示と非表示を制御します。次の4桁の16進数(左から)は上位と下位の列を決定します。例えば#0407は4番目と7番目の列を有効にします。 | |
注釈: | ピクセルグラフィックスモードではカーソルは表示されません。 |
用例: | |
cursor(BLOCK_CURSOR) | |
関連事項: | graphics_mode, text_rows |
書式: | include sort.e s2 = custom_sort(i, s1) |
解説: | s1のシーケンスの要素をソートしますが、ルーチンid iによる比較関数が使用されます。 |
注釈: | あなたの用意した比較関数を使うにはEuphoriaのcompare()と同様に引数が2つ必要となります。2つのオブジェクトの比較結果として-1や0または1が返されます。 |
プログラム例: | demo\csort.ex |
関連事項: | sort, compare, routine_id |
書式: | s = date() |
解説: | シーケンスに対して次の情報を返します: |
{ year, -- 年 : 1900年から month, -- 月 : 1から12(1月 = 1) day, -- 日 : 1から開始 hour, -- 時 : 0 から 23 minute, -- 分 : 0 から 59 second, -- 秒 : 0 から 59 day of the week, -- 曜 : 日曜日 = 1 day of the year} -- 週 : 1月の1週目 = 1 | |
注釈: | 実際は1900年を基点としたそれ以降の値が年数として返されます(その年の最後の2桁でない)。年が2000のとき値は100になります。そのほかにも年が2001のとき値は101になります。 |
用例: | |
now = date() -- 現在: {95,3,24,23,47,38,6,83} -- すなわち、1995年3月24日(金曜日) 午後11:47:38 1995年1月1日より83日目経過 | |
関連事項: | time |
書式: | include dll.e i1 = define_c_func(x1, x2, s1, i2) |
解説: | 値を返すC言語関数またはマシン語ルーチンのどちらか一方の特徴を定義します。i1にはルーチンidとして知られている小さな整数の値が返されます。このルーチンIDはc_func()の最初の引数でありEuphoriaから関数を呼び出すため使用されます。
C言語関数を定義するさい、x1はC言語関数を含むライブラリのアドレスであり、x2はC言語関数の名前であり、x1はopen_dll()によって返された値です。C言語関数が見つからないときは、ルーチンIDに-1を返します。Windowsでは、関数名の前に接頭辞に'+'を付けることができます。これはEuphoriaが関数を使うときにcdecl呼び出し規約を使用するという意味です。規定値では、EuphoriaはC言語関数がstdcall規約であると仮定して適用します。 マシン語コードを定義するさい、x1には""や{}といった空のシーケンスを指定して、さらにx2はマシン語コードのルーチンのアドレスを指定する必要があります。また、allocate()でマシン語コードを割り当てるため使用するメモリーブロック領域の割り当てを行うことができます。Windowsでは、慣例としてマシン語ルーチンはstdcall呼び出し規約で扱われますが、cdecl規約を使用したいならば代わりに、x2をアドレス(address)とみなして{'+', address}というコードを記述します。 s1は関数の引数の型のリストです。i2は関数から返される値の型です。C言語の型のリストは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 | |
C言語関数の定義はEuphoria→C言語トランスレータによって生成されることがあり、その場合はEuphoriaのデータを渡すことができ、Euphoriaのデータを受け取って戻すことができます。Euphoriaの型のリストはdll.eに収録されています: | |
global constant E_INTEGER = #06000004, E_ATOM = #07000004, E_SEQUENCE= #08000004, E_OBJECT = #09000004 | |
注釈: | どのようなC言語整数型またはポインタ型であっても値を渡したり返したりできます。EuphoriaのアトムをC言語のdoubleまたはfloatとして渡したり、C言語のdoubleまたはfloatをEuphoriaのアトムとして返したりできます。
引数の型の大きさが4byte以下のものは全て同じ方法で渡されるので、4byteの引数の型を使用するさいには正確な型の大きさを選ぶ必要はありません。また、正数または負数の間かどうか区別するときに関数の返値の型を指定するために重要になるかもしれません。 現在のEuphoriaの仕様では、C言語の構造体を値として渡したりC言語の構造体を受け取ることができません。構造体のポインタのみ渡したり構造体のポインタを返値として受けることができます。 もし値を返すC言語関数に関心がないのでしたら、define_c_proc()で定義を行いc_proc()で手続きとして呼び出すことができます。 いくつかのルーチンは共有ライブラリ - この場合はWindows APIです - では64bit整数を引数のうちひとつ渡すことが求められます。そのようなデータ型がC言語に存在するとしても、Euphoriaには実装されていません。しかし、回避方法があります:
もし外部ルーチンが64bit整数を返すならば、上述したように返値の型は変更されてしまい動作しません。ルーチンを呼び出す(Windowsでは呼び出し規約を確認します)マシン語ラッパーを設計する場合はedx:eaxに整数値を返して復帰なければなりません。Euphoriaの関数をコードにしてcall()でマシン語を呼び出して適切な2つのアトム2つのパーツを一組にしてから復帰を行い、典型的な { 下位32bit, 上位32bit } のシーケンスを返します。2つのパーツを再構築する方法は整数または負数の指定がなされた返値に依存します。 もし浮動小数点の値を返すcdecl規約のC言語ルーチンをexwで使用する場合は動作しません。理由としてWatcom Cコンパイラが(exwをビルドするために使用される)cdecl規約の浮動小数点の返値を一般的ではない方法で扱うためです。 マシン語ルーチンに浮動小数点の値を渡す場合はc_func()よりcall()を使用したほうが高速であり、poke()で浮動小数点をメモリーに格納するためにatom_to_float64()を使用する必要がありません。 ex.exe (DOS)はWATCOM 浮動小数点ルーチン(ハードウェア浮動小数点インストラクションが存在する場合はそれを使用します)を呼び出して使用できますが、一般に浮動小数点値は整数レジスタのペアとしてよりも浮動小数点値レジスタのペアとして渡したり返したほうがよいとされています。 それらの挙動を観察するにはWatcomのいくつかのコード逆アセンブルをする必要があります。 |
用例: | |
atom user32 integer LoadIcon -- user32.dllを開きます。 - C言語関数LoadIconAが含まれています。 user32 = open_dll("user32.dll") -- C言語ポインタとC言語整数を引数として持ちます。 -- 返値はC言語整数です。 LoadIcon = define_c_func(user32, "LoadIconA", {C_POINTER, C_INT}, C_INT) -- "LoadIconA"に関して理解するために -- stdcall規約が必要なLoadIconAを例とします。 -- それらはすべてのWIN32 APIでは標準的なdllルーチンです。 -- なお、cdecl規約を指定するには"+LoadIconA"を使用します。 if LoadIcon = -1 then puts(1, "LoadIconA could not be found!\n") end if | |
関連事項: | euphoria\demo\callmach.ex, c_func, define_c_proc, c_proc, open_dll, platform.doc |
書式: | include dll.e i1 = define_c_proc(x1, x2, s1) |
解説: | C言語関数またはマシン語ルーチンのどちらか一方の特徴を定義してEuphoriaのユーザプログラムから手続きとして呼び出します。i1にはルーチンidとして知られている小さな整数の値が返されます。このルーチンIDはc_proc()の最初の引数でありEuphoriaからルーチンを呼び出すのに使用されます。
C言語関数を定義するさい、x1はC言語関数を含むライブラリのアドレスであり、x2はC言語関数の名前であり、x1はopen_dll()によって返された値です。C言語関数が見つからないときは、ルーチンIDに-1を返します。Windowsでは、関数名の前に接頭辞に'+'を付けることができます。これはEuphoriaが関数を使うときにcdecl呼び出し規約を使用するという宣言です。規定値では、EuphoriaはC言語関数がcdecl規約であると仮定して適用します。 マシン語コードを定義するさい、x1には""や{}といった空のシーケンスを指定して、さらにx2はマシン語コードのルーチンのアドレスを指定する必要があります。また、allocate()でマシン語コードを割り当てるため使用するメモリーブロック領域の割り当てを行うことができます。Windowsでは、慣例としてマシン語ルーチンはstdcall呼び出し規約で扱われますが、cdecl規約を使用したいならば代わりに、x2をアドレスとして{'+', アドレス}というコードを記述します。 s1は関数の引数の型のリストです。C言語の型のリストはdll.eと上記に収録されています。これらはマシン語の引数を定義するためにも同様に使用できます。 |
C言語関数の定義はEuphoria→C言語トランスレータによって生成されることがあり、その場合はEuphoriaのデータを渡すことができ、Euphoriaのデータを受け取って戻すことができます。Euphoriaの型のリストはdll.eと上記に収録されています。 | |
注釈: | どのようなC言語整数型またはポインタ型であっても値を渡したりできます。EuphoriaのアトムをC言語のdoubleまたはfloatとして渡したりできます。 引数の型の大きさが4byte以下のものは全て同じ方法で渡されるので、4byteの引数の型を使用するさいには正確な型の大きさを選ぶ必要はありません。 現在のEuphoriaの仕様では、C言語の構造体を値として渡すことができません。構造体のポインタのみ渡すことができます。 C言語関数の返値を受け取ることはできますが無視されます。もしC言語関数の返値を使用したい場合は、define_c_func()で定義してc_func()で関数を呼び出してください。 いくつかのルーチンは共有ライブラリ - この場合はWindows APIです - では64bit整数を引数のうちひとつ渡すことが求められます。そのようなデータ型がC言語に存在するとしても、Euphoriaには実装されていません。しかし、回避方法があります:
もし外部ルーチンが64bit整数を返すならば、上述したように返値の型は変更されてしまい動作しません。ルーチンを呼び出す(Windowsでは呼び出し規約を確認します)マシン語ラッパーを設計する場合はedx:eaxに整数値を返して復帰なければなりません。Euphoriaの関数をコードにしてcall()でマシン語を呼び出して適切な2つのアトム2つのパーツを一組にしてから復帰を行い、典型的な { 下位32bit, 上位32bit } のシーケンスを返します。2つのパーツを再構築する方法は整数または負数の指定がなされた返値に依存します。 |
用例: | |
atom user32 integer ShowWindow -- user32.dllを開きます。 - C言語関数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 not found!\n") end if | |
関連事項: | c_proc, define_c_func, c_func, open_dll, platform.doc |
動作環境: | WIN32, Linux, FreeBSD |
書式: | include dll.e a1 = define_c_var(a2, s) |
解説: | a2はopen_dll()によって返されたLinuxまたはFreeBSDの共有ライブラリか、Windowsの.dllファイルのアドレス値です。sはライブラリ内で定義されたC言語のグローバル変数名です。a1には変数sのメモリーアドレスが返されます。 |
注釈: | 既にC言語変数のアドレスがあり、その変数の型や構造が判明しているのであれば、peek()およびpoke()によって変数の値を読み書きすることができます。 |
プログラム例: | euphoria/demo/linux/mylib.exu |
関連事項: | c_proc, define_c_func, c_func, open_dll, platform.doc |
書式: | include file.e x = dir(st) |
解説: | stに指定されたファイルまたはディレクトリの情報を返します。もしファイルまたはディレクトリが無い場合は-1を返します。WindowsまたはDOSではstに*および?といったワイルドカードを含めて複数のファイルを選択することができます。
この情報はDOSのDIRコマンドで取得できるものと類似しています。シーケンスの要素ごとに1つのファイルまたはサブディレクトリを含むものがシーケンスとして返されます。 stにディレクトリ名を指定するときは、DOSのDIRコマンドと同様に"."と".."のエントリがあるかもしれません。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' -- ボリュームIDエントリ 'a' -- アーカイブファイル | |
通常のファイルは特殊な属性を持たないためこのフィールドは空文字""になります。 | |
注釈: | すなわち、C:\のようにルートディレクトリは"."または".."を持ちません。
この関数はファイルまたはディレクトリが存在するか調べるために使用されることがあります。 WIN32では、 stに長いファイルまたはディレクトリ名を含んだパスを何処でも扱うことができます。 Linux/FreeBSDでは、現在のところ属性は'd'のみ存在します。 DOS32: ファイル名 D_NAME はDOS標準8.3形式で返されます(より良い解決策はアーカイブウェブページを参照してください)。 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" になります。 | |
プログラム例: | bin\search.ex |
関連事項: | wildcard_file, current_dir, open |
動作環境: | DOS32 |
書式: | include image.e display_image(s1, s2) |
解説: | ピクセルグラフィックススクリーンにイメージs2を含む2次元シーケンスを位置s1に表示します。s1は2要素のシーケンス{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列のピクセルからなる小さなイメージを表示します。 -- 最初の列は{20,30}から始まってピクセルは(7)から描画されます。 -- 上の列には5ピクセル含まれています。 -- 最後の列は {25,33}から始まって6ピクセル含んでいます。 | |
プログラム例: | demo\dos32\bitmap.ex |
関連事項: | save_image, read_bitmap, display_text_image |
書式: | include image.e display_text_image(s1, s2) |
解説: | 文字の行s1[1]と桁s1[2]および属性s2を含む2次元シーケンスを表示します。s2は入れ子になったシーケンスであり、シーケンスの文字列と属性が表示されます。左上の文字はs1から表示されます。ほかの文字は右または、この位置の下に現れます。属性は、前の文字の前景色と背景色を意味します。DOS32では、背景色の属性は前景色を16倍して加算したものにする必要があります。 |
注釈: | s2は以前save_text_image()を呼び出した結果または、貴方が作成したものであることがあります。
このルーチンはテキストモードでのみ動作します。 テキストモードグラフィカルユーザインタフェースで以前のスクリーンの状態を損なうことなく"ポップアップ"ダイアログボックス、ドロップダウンの表示・非表示をするためにsave_text_image()/display_text_image()を使用するかもしれません。 テキストイメージとしてのシーケンスの長さは全て同一である必要はありません。 なお、この関数は半角英数専用です。ShiftJISなどのマルチバイト文字列に対しては使用できません。 |
用例: | |
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 |
動作環境: | DOS32 |
書式: | include machine.e s2 = dos_interrupt(i, s1) |
解説: | DOSソフトウェア割り込み番号 iを呼び出します。s1は割り込みルーチンの入力(引数)として用いられる16bitのレジスタ値を持つ10個の要素のシーケンスで構成されています。同様にs2はレジスタ値を持つ10個の要素のシーケンスで呼び出し後の返値です。machine.eでは出力・入力シーケンスに対するレジスタの値の順列は次のように宣言されています。 |
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ソフトウェア割り込みを使うとフロッピーディスクの初期化、コンピュータの再起動など多種多様な特殊操作を何でも行うことができます。これらの割り込みに関する解説はPeter Norton's "PC Programmer's Bible"などの技術資料を参照するかRalf Brown's Interrupt Listをウェブからダウンロードしてください。 http://www.cs.cmu.edu/afs/cs.cmu.edu/user/ralf/pub/WWW/files.html |
用例: | |
sequence registers registers = repeat(0, 10) -- レジスタを設定する必要はありません。 -- DOS割り込み番号5の呼び出し: スクリーンの印刷 registers = dos_interrupt(#5, registers) | |
プログラム例: | demo\dos32\dosint.ex |
関連事項: | allocate_low, free_low |
動作環境: | DOS32 |
書式: | include graphics.e draw_line(i, s) |
解説: | ピクセルグラフィックスモードで色 iを用いて2点以上のsを結んで線を描きます。 |
用例: | |
draw_line(WHITE, {{100, 100}, {200, 200}, {900, 700}}) -- これは3点のシーケンスを接続して白線を描画します。 -- つまり、{100, 100} から{200, 200}まで線を引き、 -- {200, 200} から {900, 700}まで別の線を -- 引きます。 | |
関連事項: | polygon, ellipse, pixel |