* NDKで「Lua」を組み込んでみる [#m2b06be5] 「Lua」は、ポータブルな組み込み型スクリプト言語です。 現在、スクリプト言語用のフレームワークが、以下のプロジェクトで作成されています。 - http://code.google.com/p/android-scripting/ ここでは、NDKの作成手順を紹介するために、Luaを使用してみます。 ここで紹介するプログラムはサンプルコードのため、実際の動作には適していませんので、ご注意ください。 ** Luaライブラリの作成 [#yc414537] まず、Luaのソースコードをダウンロードします。 - http://www.lua.org/ から、lua-5.1.4.tar.gz をダウンロード ${ndk}/sources/samples/lua-5.1.4に展開 - srcディレクトリにAndroidからの呼び出しコードのファイルを追加します touch src/android.c - ${ndk}/sources/samples/lua-5.1.4/Android.mkを作成します 中身は、include $(call all-subdir-makefiles)のみです - ${ndk}/sources/samples/lua-5.1.4/src/Android.mkを作成します 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 -- locale.hの部分でエラーが出たので、一か所修正(エラー部分を削除) ** Luaアプリの作成 [#zed25ded] Luaアプリケーションを格納するディレクトリを生成して、Application.mkを作成します。 - apps/hellolua/Application.mkの作成 -- APP_PROJECT_PATH := $(call my-dir)/project -- APP_MODULES := lua EclipseでLuaを呼び出すアプリケーションを作成します。 - ${ndk}/app/hellolua/projectに作成 - EditText, Button, TextViewを配置 #ref(app.png) ** Javaのnativeメソッドの定義 [#s286fd89] 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 ** Nativeメソッドを定義する [#idc764af] 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); } ** 実行 [#z05054e3] makeして、Eclipseからアプリを実行します。 make APP=hellolua Eclipse: Run as Android Application #ref(run.png) ---- プレゼンテーション資料は、以下からダウンロードできます。 #ref(AndroidNDKLua.pdf)