0Pricing
Lua Academy · レッスン

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))
end

ffi.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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. FFIの基礎:ffi.cdefとffi.load
  2. FFIによるC関数の呼び出し
  3. FFIにおけるポインター、構造体、配列
  4. コールバック:Lua関数をCに渡す
← Lua Academyに戻る