この初版はLua 5.0向けに書かれています。後のバージョンにもほぼ当てはまりますが、いくつかの違いがあります。
第4版はLua 5.3を対象としており、Amazonなどの書店で入手可能です。
本書をご購入いただくことで、Luaプロジェクトの支援にもなります。


24 – C APIの概要

Luaは*組み込み言語*です。つまり、Luaはスタンドアロンのパッケージではなく、他のアプリケーションとリンクしてLuaの機能をそれらのアプリケーションに組み込むことができるライブラリです。

疑問に思うかもしれません:Luaはスタンドアロンプログラムではないのに、なぜ本書全体を通してLuaをスタンドアロンで使用してきたのでしょうか?この疑問の答えは、Luaインタプリタ(実行ファイル`lua`)です。このインタプリタは、Luaライブラリを使用してスタンドアロンインタプリタを実装する小さなアプリケーション(500行未満のコード)です。このプログラムは、ユーザーとのインターフェースを処理し、ユーザーのファイルや文字列を受け取ってLuaライブラリに渡し、Luaライブラリが作業の大部分(Luaコードの実際の実行など)を行います。

ライブラリとして使用してアプリケーションを拡張できるこの機能こそ、Luaを*拡張言語*たらしめるものです。同時に、Luaを使用するプログラムは、Lua環境に新しい関数を登録できます。このような関数はC(または他の言語)で実装されており、Luaで直接記述できない機能を追加できます。これがLuaを*拡張可能な言語*たらしめるものです。

Luaのこれら2つの側面(拡張言語としての側面と拡張可能な言語としての側面)は、CとLuaの2種類の相互作用に対応しています。1つ目の種類では、Cが制御権を持ち、Luaはライブラリです。この種類の相互作用におけるCコードは、*アプリケーションコード*と呼びます。2つ目の種類では、Luaが制御権を持ち、Cはライブラリです。ここでは、Cコードは*ライブラリコード*と呼ばれます。アプリケーションコードとライブラリコードはどちらも、C APIと呼ばれる同じAPIを使用してLuaと通信します。

C APIは、CコードがLuaと対話できるようにする関数のセットです。Luaグローバル変数の読み書き、Lua関数の呼び出し、Luaコードの部分的な実行、C関数の登録(後でLuaコードから呼び出せるようにするため)などを行うための関数が含まれています。(このテキスト全体を通して、「関数」という用語は実際には「関数またはマクロ」を意味します。APIはいくつかの機能をマクロとして実装しています。)

C APIは、Luaとは大きく異なるCの*モジュール運用*に従います。Cでプログラミングする場合、型チェック(および型エラー)、エラー回復、メモリ割り当てエラー、およびその他のいくつかの複雑さの原因に注意する必要があります。APIのほとんどの関数は、引数の正当性をチェックしません。関数を呼び出す前に、引数が有効であることを確認するのはあなたの責任です。ミスをすると、適切なエラーメッセージではなく、「セグメンテーションフォールト」エラーなどが発生する可能性があります。さらに、APIは柔軟性とシンプルさを重視しており、使いやすさを犠牲にする場合があります。一般的なタスクには、複数のAPI呼び出しが必要になる場合があります。これは退屈かもしれませんが、エラー処理、バッファサイズなど、すべての詳細を完全に制御できます。

タイトルが示すように、この章の目的は、CからLuaを使用する際に何が関係するかについての概要を示すことです。今はすべての詳細を理解しようとする必要はありません。詳細は後で説明します。ただし、Luaリファレンスマニュアルで特定の関数に関する詳細を見つけることができることを忘れないでください。さらに、Luaディストリビューション自体にAPIの使用例がいくつかあります。Luaスタンドアロンインタプリタ(`lua.c`)はアプリケーションコードの例を提供し、標準ライブラリ(`lmathlib.c`、`lstrlib.c`など)はライブラリコードの例を提供します。

これからは、Cプログラマーの帽子をかぶります。「あなた」と言うときは、Cでプログラミングしているとき、またはあなたが書いたCコードによって擬人化されたあなたのことを指します。

LuaとCの間の通信における主要なコンポーネントは、遍在する仮想*スタック*です。ほとんどすべてのAPI呼び出しは、このスタック上の値に対して操作を行います。LuaからCへ、そしてCからLuaへのすべてのデータ交換は、このスタックを介して行われます。さらに、スタックを使用して中間結果を保持することもできます。スタックは、LuaとCの間の2つのインピーダンスミスマッチを解決するのに役立ちます。1つ目は、Luaがガベージコレクションされるのに対し、Cは明示的な割り当て解除を必要とすることです。2つ目は、Luaの動的型付けとCの静的型付けの衝突によるものです。スタックについては、セクション24.2で詳しく説明します。