AndroidでPOCO C++ Librariesの実行方法

http://pocoproject.org/ ですが、1.4.2 から Android 対応しているのですが、マニュアルがドキュメント不足でいまいちわからなかったので、ここにメモしておきます。

ライブラリ自体のコンパイル方法

http://pocoproject.org/docs/99300-AndroidPlatformNotes.html どおりです。Ubuntu 12.04 (x64) でも MinGW でもどちらでもコンパイルできました。Ubuntu x64 の場合、aptitude install ia32 する必要があります。

こんな感じで、my-android-toolchain を作って、

export NDK=$HOME/android-ndk-r7c
$NDK/build/tools/make-standalone-toolchain.sh --platform=android-8 --install-dir=$HOME/my-android-toolchain
export PATH=$HOME/my-android-toolchain/bin:$PATH

こんな感じでコンパイルできます。

cd poco-1.4.3p1
./configure --config=Android --no-samples --no-tests
make -s -j4
make -s -j4 ANDROID_ABI=armeabi-v7a

そして、--platform=android-8 を --arch=x86 に変え、ANDROID_ABI=x86 にすると、x86 Android でも動作します。エミュレータで高速に動作するようになります。

ndk-build との併用方法

この部分がドキュメント不足でした。

まず、Application.mk に

APP_STL      := gnustl_static

gnustl_static でも gnustl_shared でもどちらでも動作しますが、gnustl_shared の場合、Java 側から、System.loadLibrary("gnustl_shared"); する必要があります。

Android.mk に

LOCAL_CPP_FEATURES += exceptions rtti

を追加し、更に、

  • LOCAL_CFLAGS には -Ipoco-1.4.3p1/Foundation/include -Ipoco-1.4.3p1/Net/include -Ipoco-1.4.3p1/Xml/include -Ipoco-1.4.3p1/Util/include を追加します。
  • LOCAL_LDLIBS の先頭に、-Lpoco-1.4.3p1/lib/Android/armeabi-v7a -lPocoNet -lPocoXml -lPocoUtil -lPocoFoundation を追加します。
  • LOCAL_STATIC_LIBRARIES に、libgnustl_static を追加します。

poco-1.4.3p1 へのパスは適切に変えてください。exceptions rtti は動作させるのに必須です。それ故、APP_STL は gnustl を使わないとダメです。

NativeActivity を使っているのですが、AndroidManifest.xml は例えば、こんな感じにします。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example.hoge"
      android:versionCode="1"
      android:versionName="1.0">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-sdk android:minSdkVersion="10" />

    <application android:label="@string/app_name" android:hasCode="true" android:debuggable="true">
        <activity android:name="android.app.NativeActivity" android:label="@string/app_name">
            <meta-data android:name="android.app.lib_name" android:value="hoge" />
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest> 

HTTP 通信とか、StringTokenizer とかがちゃんと動作するところまで確認しました。

ただし、POCO の Thread.start() が Android NDK r7c + POCO 1.4.3p1 の組み合わせでは正常に動作しませんでした。原因不明。自分で Pthread を使う分には問題無いです。

(追記)最初にこのブログを書いた際、大幅に間違いを含んでいたので色々修正しました。