2011.11.11
【Android NDK】デバッグ出力
デバッグ出力だけでこんなに面倒なのか・・・
SDKのLog.dのようなものはNDK側でも使える。
使い方的にはこんな感じ
#include <android/log.h> __android_log_print( ANDROID_LOG_INFO, "val:%d", 10 );
Android.mkのLOCAL_LDLIBSに-llogをつけないと実行されないので注意
これでLogCatには結果は出てくるのだが日本語がうまく表示されない。
いろいろやったところ、ログ出力はUTF-8で行わないといけないらしい。
しかし、C言語標準にUTF-8へ変換する関数がないのでどうにかして変換をおこなわないと表示できない。
案1) ソースコードをUTF-8へ保存する
一応この方法で日本語表示が正しくなることは確認できた。
しかし、すべての文字列処理をUTF-8にしないといけない。
逆にそちらのほうが大変ということに気づいてあきらめる。
案2) ライブラリを導入してUTF-8変換が行えるようにする。
libiconvを導入することでC言語で変換できるようになるらしい。
Link:libiconv - GNU Project - Free Software Foundation (FSF)
だけど今ひとつ組み込み方がわからない。
案3) JavaでUTF-8変換を行う
Javaでやれば余裕なわけです。
JNIからうまくJavaを使いUTF-8変換を行う
結局、案3の方向で行うことにしました。
1. va_listを使ってSjis文字列を作成 2. そのままByteArrayに変換しJNI使ってJAVAを呼び出す 3. 渡されたByteArrayをStringへ変更しLog.dなどを使って表示
Javaで変換するのであればそのままログ出力までしてしまいましょうという考えになりました。
2.の部分の処理がこんな感じ。
/** * Javaのログ出力を呼び出す * @param szText javaへ渡す文字列 */ static void callJavaLogOut( char *szText ) { jbyteArray jaryStr; char szClassName[256]; JNIEnv *env = g_pJniEnv; //クラス名作成 szClassName[0] = '\0'; strcat( szClassName, PROJECT_PACKAGE_NAME ); strcat( szClassName, "/Utility" ); //文字列長さ分の配列を作成 jaryStr = (*env)->NewByteArray( env, strlen( szText ) ); //内部に文字列データをコピーする (*env)->SetByteArrayRegion( env, jaryStr, 0, strlen( szText ), (jbyte*)szText ); //ログ出力関数の呼び出し jclass jcls = (*env)->FindClass( env, szClassName ); jmethodID mj = (*env)->GetStaticMethodID( env, jcls, "LogOut", "([B)V"); (*env)->CallStaticObjectMethod( env, jcls, mj, jaryStr ); //後処理 (*env)->DeleteLocalRef( env, jaryStr ); (*env)->DeleteLocalRef( env, jcls ); }
g_pJniEnvはどこかで呼ばれたJNIEnvをグローバルに保存したものになる。
これは危険かもしれないので要確認ですね。
クラス名については"L(フルパスクラス名);"ってやるとだめぽい。
区切りはすべて"/"になる。
Android NDKネイティブプログラミング 出村 成和 秀和システム 2011-07 |
関連記事