「Lua」は、ポータブルな組み込み型スクリプト言語です。
現在、スクリプト言語用のフレームワークが、以下のプロジェクトで作成されています。
ここでは、NDKの作成手順を紹介するために、Luaを使用してみます。
ここで紹介するプログラムはサンプルコードのため、実際の動作には適していませんので、ご注意ください。
まず、Luaのソースコードをダウンロードします。
${ndk}/sources/samples/lua-5.1.4に展開
touch src/android.c
中身は、include $(call all-subdir-makefiles)のみです
LOCAL_MODULE := lua LOCAL_SRC_FILES := lapi.c lcode.c ldebug.c ldo.c ldump.c \ lfunc.c lgc.c llex.c lmem.c lobject.c lopcodes.c lparser.c \ lstate.c lstring.c ltable.c ltm.c lundump.c lvm.c lzio.c \ Luaxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c loslib.c \ ltablib.c lstrlib.c loadlib.c linit.c android.c LOCAL_LDLIBS := -L${SYSROOT}/usr/lib -llog
Luaアプリケーションを格納するディレクトリを生成して、Application.mkを作成します。
EclipseでLuaを呼び出すアプリケーションを作成します。
Javaのクラスにnativeメソッドを定義します
public class HelloLua extends Activity { ... public native String doCall(String script);
クラス名を指定して、JNIのヘッダーを生成します
javah -jni -classpath ${ndk}/apps/hellolua/project/bin -d ${ndk}/sources/samples/lua-5.1.4/src jp.hews.hellolua.HelloLua
JNIの初期化ルーチンでLuaを初期化して、print関数を登録します。 Nativeメソッドの呼び出しルーチンでスクリプトを渡して、実行し、プリント用のバッファを取得します。
/* File: android.cpp - last edit: Hideo Kinami 7-Jul-2009 Copyright(C) 2009 by Hideo Kinami. All rights reserved. */ #include <stdio.h> #include <string.h> #include "lua.h" #include "lauxlib.h" #include "jp_hews_hellolua_HelloLua.h" #include "loghelper.h" #define LOG_TAG "Lua" static char fgBuff[1024]; static size_t fgLen = 0; static void put(const char* fmt, ...) { va_list ap; va_start(ap, fmt); if ( sizeof(fgBuff) <= fgLen ) { return; } int len = vsnprintf(&fgBuff[fgLen], sizeof(fgBuff)-fgLen, fmt, ap); fgLen += len; } static int print(lua_State *L) { int n=lua_gettop(L); int i; for (i=1; i<=n; i++) { if (i>1) { LOGI("\t"); put("\t"); } if (lua_isstring(L,i)) { LOGI("%s",lua_tostring(L,i)); put("%s",lua_tostring(L,i)); } else if (lua_isnil(L,i)) { LOGI("%s","nil"); put("%s","nil"); } else if (lua_isboolean(L,i)) { LOGI("%s",lua_toboolean(L,i) ? "true" : "false"); put("%s",lua_toboolean(L,i) ? "true" : "false"); } else { LOGI("%s:%p",luaL_typename(L,i),lua_topointer(L,i)); put("%s:%p",luaL_typename(L,i),lua_topointer(L,i)); } } return 0; } static lua_State *gLua = 0; jint JNI_OnLoad(JavaVM *vm, void * reserved) { fgBuff[0] = 0; fgLen = 0; gLua = lua_open(); lua_register(gLua,"print",print); return JNI_VERSION_1_6; } /* * Class: jp_hews_hellolua_HelloLua * Method: doCall * Signature: (Ljava/lang/String;)Ljava/lang/String; */ jstring JNICALL Java_jp_hews_hellolua_HelloLua_doCall (JNIEnv * env, jobject jobj, jstring jstr) { const jbyte *str = (*env)->GetStringUTFChars(env, jstr, 0); LOGI("script = %s", str); // clear Buff; fgLen = 0; fgBuff[0] = 0; if (luaL_dostring(gLua, str)) { LOGE("%s\n",lua_tostring(gLua,-1)); } (*env)->ReleaseStringUTFChars(env, jstr, str); return (*env)->NewStringUTF(env, fgBuff); }
makeして、Eclipseからアプリを実行します。
make APP=hellolua Eclipse: Run as Android Application
プレゼンテーション資料は、以下からダウンロードできます。