LoginSignup
3
3

More than 5 years have passed since last update.

Androidでネイティブコードを利用する

Last updated at Posted at 2016-12-17

前回はOpenGLESの設定まで解説しました、今回は続きを進めようとおもいましたが、AndroidではC/C++コードを利用できることが分かったので、ちょっと回り道を。

OpenGLのコードはC/C++が圧倒的に多いので、「その資産が利用できる!」と期待してみたものの利用方法が想像以上に壁でした。まだ全て把握できていませんが、私が理解した範囲をまとめておきます。

最新のAndroid Studioでの情報があまりないので、かなり手探りですすめていますので、間違っている箇所などあればご指摘いただけると助かります。

準備

Android Studio2.2を準備します。

Android Studio2.2では新規プロジェクト作成で"C/C++を利用しますか?"というチェックボックスが表示されるので、まずはこれをONにします。

c.png

ディレクトリ構成を確認

新規プロジェクトの構成を確認します。左側のプロジェクト構造を"Android"から"Project"に変更し全てのファイルが確認できるようにします。

以下のファイルがあればOKです。

  • app/CMakeList.txt
  • app/src/main/cpp/native-lib.cpp

buildしてみる

一度buildしてみると、画面にはTextViewが表示されると思います。
MainActivity.javaからcpp/native-lib.cのコードが呼び出されているのがわかります。

public class MainActivity extends AppCompatActivity {

    // native-lib.cはコンパイルでlibraryになるようで、それをここで読み込んでいます。
    // import みたいなものでしょうか。
    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());
    }

    /**
     * native-lib.cで実装した関数を定義しているようです。
     */
    public native String stringFromJNI();
}

native-lib.cppを確認

デフォルトで下記のコードが記述されていると思います。
このコードをみると、
パッケージ、プロジェクト名、関数名をアンダースコアでつないでいるようです。多分これが書式なのかな。

という記述で定義されているようです。戻り値も"jstring"という形ですね。
これはAndroid NDKだったか、JNI(Java native interface)の型かと思います。

#include <jni.h>
#include <string>

extern "C" 
jstring
Java_com_test_opengl_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

 テスト関数を定義してみる。

まずは、extern "C"が全体にかかるように下記のように修正します。

extern "C" {

// ここに関数をいれます。

}

適当にテスト関数を記述します。引数はお決まりっぽいので同じものをいれます。

extern "C" {

    // stringFromJNIの記述は省略

    void
    Java_quad_jp_opengl_MainActivity_sayHello(JNIEnv *env, jobject){
        std::cout << "Hello World" << std::endl;
    }
}

もちろんMainActivityの方にも関数を定義します。

public native void sayHello();

ビルドすると、特にエラーなくおわりました、coutの出力はどこで確認できるかはわかりませんでした...orz

とりあえず、C側で処理を実行する方法は分かったので、これで前回のコードを修正してみます。後ほどここに追記ます。

参考情報

Android NDK(公式ページ詳しい設定方法があり)

一部翻訳されているページがありますが、翻訳がイマイチで少し混乱します。
プロジェクトへの C / C++ コードの追加

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3