web-dev-qa-db-ja.com

Android ndk / jniでC ++を使用する

すべてのndkサンプルは、ヘッダーでexternとして宣言され、cppファイルで定義された基本的なC関数のみを使用します。次に、jniコールバックを含むCファイルにヘッダーファイルを含めた後、すべてが正常に動作します。

Android ndkでC++クラスを使用できますか?私のアプリケーションはネイティブアクティビティではなく、重要なJava=部分がありますが、 CPUを集中的に使用する計算のためにネイティブCコードを呼び出します(すでにC++で記述されており、クラスやその他のC++のものを使用しています)。

ここに私のhello-worldのような構造があります:

ファイル「first.h」

#ifndef FIRST_H
#define FIRST_H

class Test
{};

#endif /* FIRST_H */

ファイル「second.cpp」

#include <jni.h>
#include "first.h"

#ifdef __cplusplus
extern "C" {
#endif

jint Java_com_example_twolibs_TwoLibs_add( JNIEnv*  env,
                                      jobject  this,
                                      jint     x,
                                      jint     y )
{
    Test t;
    return 0;
}

#ifdef __cplusplus
}
#endif

そして最後にAndroid.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := libtwolib-second
LOCAL_SRC_FILES := second.cpp

include $(BUILD_SHARED_LIBRARY)

かなり基本的ですが、コンパイルされません。 .cファイルでsecond.cppを回すと、ヘッダーファイルをインクルードするときにエラーが発生します。これは、C++ファイルではないためだと思います。

error: expected '=', ',', ';', 'asm' or '__attribute__' before 'Test'

.cppにすると、次のエラーが発生します。

make: *** No rule to make target `/cygdrive/c/Android-ndk-r5c/samples/twolibs/jni/second.c', needed by `/cygdrive/c/Android-ndk-r5c/samples/two-libs/obj/local/armeabi/objs/twolib-second/second.o'.  Stop.

どのように私はそれをコンパイルすることができますか?

ありがとう

34
pot2mayo

NDKでC++を使用できますが、C++コードのファイルには.cpp拡張子が必要です。

Android-MK.htmlから:

C++ソースファイルのデフォルトの拡張子は「.cpp」です。ただし、変数LOCAL_CPP_EXTENSIONを定義することにより、別のものを指定することが可能です。最初のドットを忘れないでください(つまり、「。cxx」は機能しますが、「cxx」は機能しません)。

15
Michael

Android専用のすべてのネイティブライブラリを再コンパイルする必要があります。通常、これらのライブラリをコンパイルしてリンクするときにAndroidそれらはglibcにリンクされますが、残念ながらAndroidは、ライセンスとパフォーマンスの問題のため、glibcを使用しません。Androidは、glibcと呼ばれるlibcの簡略版を使用します。通常の機能のほとんどで、glibcに一致するシンボル名があります。しかし、私が知る限り、libcにはstringsに関連するいくつかの機能がなく、posixのサポートもありません。ネイティブライブラリが非推奨の機能のいずれかを使用している場合、サポートされている代替機能を使用してそれらの回避策を見つける必要がありますlibcを使用し、それに応じてライブラリをコーディングします。

また、正しく指摘したように、NDKを使用してJava(Android app/fwk)をネイティブの世界(C++)にインターフェースする必要があります。

これは、私の経験ではAndroidでのネイティブライブラリのコンパイル(Androidの移植)は非常に簡単に聞こえますが、成功を保証するものではなく、非常に時間がかかります。

3
Alok Save

コンパイルエラーについて、最初に「second.c」と呼び、後で「second.cpp」に名前を変更したようですが、オブジェクトファイルにはまだ「second.c」という名前が含まれているため、コンパイルする前に(bdk-build)/cygdrive/c/Android-ndk-r5c/samples/two-libs/obj/local/armeabi/objs/twolib-second /ディレクトリにある* .oおよび* .dファイルを削除する必要があります

1
Bush

エラー:「=」、「、」、「;」、「asm」、または「__属性__」が「クラス」の前に必要です

「;」が欠落している古典的なケースクラスキーワードの前?想像してみて

 int functionname(int p)
 class X { } ;

これは、コンパイラメッセージに非常に簡単につながる可能性があります。一般的な複雑な要素は、実際に次のようになる場合です

 #include "someheader.h"
 class X { } ;

エラーはsomeheader.h内の最後の宣言にある/または再帰的にインクルードされたファイル/;)

0
sehe

実行:

ndk-build clean

間違ったAndroid.mkを変更すると、設定を修正してもビルドが失敗し続ける場合があります。

これがOPの意味するところだと思います このコメントについて

Android.mkを編集する

LOCAL_SRC_FILESのインスタンスを変更し、各行の先頭から./を削除します。