FFIによるC関数の呼び出し
Luaからlibcや独自の共有ライブラリ関数をオーバーヘッドなしで呼び出します。
「FFIによるC関数の呼び出し」はCoddyKit上の無料Lua Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLua Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Lua Academyコースには全4レッスンが含まれています。
C関数を直接呼び出す
ffi.cdefで宣言すると、ライブラリオブジェクトを通じて、C関数をLua関数とまったく同じように呼び出せます。引数と戻り値は自動的に変換されます。
local ffi = require("ffi")
ffi.cdef[[ double sin(double x); ]]
local m = ffi.load("m")
print(m.sin(math.pi / 2)) -- 1.0型変換
Luaの数値は、デフォルトでCのdoubleになります。FFIは、宣言されたCのパラメーター型に自動変換します。ブール値は0/1になり、文字列はconst char*になります。
printfを呼び出す
printfは可変長引数を取るC関数です。書式文字列と引数を指定し、ffi.C.printf経由で呼び出します。
ffi.cdef[[ int printf(const char *fmt, ...); ]]
ffi.C.printf("Sum: %d\n", 42)戻り値の処理
Cの戻り値は自動的にLuaの型へ変換されます。整数はLuaの数値になり、char*はlightuserdataになります(変換にはffi.stringを使用します)。
ffi.cdef[[ char *getenv(const char *name); ]]
local ptr = ffi.C.getenv("HOME")
if ptr ~= nil then
print(ffi.string(ptr))
endffi.string
ffi.string(ptr, len)はchar*ポインターをLuaの文字列に変換します。lenを指定しない場合は、ヌルバイトまで読み取ります。
エラー処理
C関数はエラーコードを返すか、errnoを設定します。戻り値を明示的に確認してください。ffi.errno()でerrnoにアクセスできます。
ffi.cdef[[ int open(const char *path, int flags); ]]
local fd = ffi.C.open("missing.txt", 0)
if fd < 0 then
print("Error:", ffi.errno())
end構造体を引数に渡す
Cの構造体は、値渡しまたはポインター渡しで渡します。ffi.newで作成してください。
ffi.cdef[[
typedef struct { int x, y; } Point;
void printPoint(Point p);
]]
local p = ffi.new("Point", {x=3, y=4})
lib.printPoint(p)ポインターを引数に渡す
ポインター引数を通じて複数の値を返す関数には、出力用ポインターを渡します。
ffi.cdef[[
void minmax(double *arr, int n, double *min, double *max);
]]
local arr = ffi.new("double[5]", {5,2,8,1,9})
local mn, mx = ffi.new("double[1]"), ffi.new("double[1]")
lib.minmax(arr, 5, mn, mx)
print(mn[0], mx[0])FFI呼び出しの性能
C関数へのFFI呼び出しのオーバーヘッドはほぼゼロで、従来のC APIを介したLuaからCへの呼び出しよりもはるかに高速です。JITによって呼び出し全体がインライン化されることもあります。
可変長引数関数
可変長引数を取るC関数(...)は、正しい型で呼び出す必要があります。曖昧さを避けるため、必要に応じて明示的な型キャストを渡してください。
ffi.C.printf("%d %f\n", ffi.cast("int", 42), ffi.cast("double", 3.14))安全に扱うための実践方法
ポインターを返す関数では、必ずNULLかどうかを確認してください。解放済みのポインターやスコープ外のポインターを決して渡さないでください。Cの割り当てにファイナライザーを関連付けるには、ffi.gcを使用します。
FFI呼び出しに関する質問
FFIはLuaの文字列をCのconst char*にどのように変換しますか?
まとめ:FFIでCを呼び出す
ライブラリオブジェクトを通じて、Lua関数と同じようにC関数を呼び出します。型変換はFFIが処理します。char*の戻り値にはffi.string、エラーにはffi.errno()、構造体や配列の引数にはffi.newを使用します。
よくある質問
「FFIによるC関数の呼び出し」レッスンは無料ですか?
はい。「FFIによるC関数の呼び出し」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Lua Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Lua Academyコースには全4レッスンが含まれています。
「FFIによるC関数の呼び出し」で何を学びますか?
Luaからlibcや独自の共有ライブラリ関数をオーバーヘッドなしで呼び出します。 ブラウザで直接実行するハンズオンコードでLua Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Lua Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのLua Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「FFIによるC関数の呼び出し」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このLua Academyレッスンでコードを書いて実行できますか?
はい。すべてのLua Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。