2011-06-21 12 views
34

すべてのndkサンプルでは、​​ヘッダのexternとして宣言され、cppファイルで定義された基本的なC関数しか使用しません。その後、jniコールバックを含むCファイルにヘッダファイルをインクルードした後、すべて正常に動作します。AndroidでC++を使用するndk/jni

android ndkでC++クラスを使用することはできますか?私のアプリケーションはネイティブのアクティビティではなく、まだ重要なJavaの部分を持っていますが、CPU集約的な計算のためのネイティブCコード(クラスやその他のC++のもので既にC++で書かれています)を呼び出します。ここで

今のstrcutureように私のハローの世界です:

ファイル "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. 

私はその事をコンパイルすることができますどのように任意のアイデア?

おかげ

答えて

15

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

アンドロイド-MK.htmlから:行方不明の

Note that the default extension for C++ source files is '.cpp'. It is however possible to specify a different one by defining the variable LOCAL_CPP_EXTENSION. Don't forget the initial dot (i.e. '.cxx' will work, but not 'cxx').

+0

コールバックCコード(Java側から呼び出されるJava_com_example_twolibs_TwoLibs_addのような呼び出しを含むファイル)は.cファイル(.cppではなく)になければなりません。さもなければ私のマシンでコンパイルされません。したがって、クラス宣言を含むヘッダファイルをインクルードしようとすると、同じエラーが発生します。 – user745189

+1

すべてを.cppファイルに変換すると、makeは次のようになります。***ターゲットエラーを作るルールはありません。つまり、makeファイルはソースファイルを見つけることができませんでしたが、.cファイルに変換するとそうなります – user745189

+0

コンパイルが必要ですが、すべてのJNI関数に 'external" C "'を追加する必要があります。 makefileのソースファイル拡張子を変更しましたか? – Michael

3

あなたは、特にAndroidのためのすべてのネイティブライブラリを再コンパイルする必要があります。通常、Android以外でこれらのライブラリをコンパイルしてリンクすると、glibcにリンクされていますが、残念なことにAndroidは使用上の問題やパフォーマンスの問題により、glibcを使用しないため、使用するすべてのサードパーティ製のネイティブライブラリのソースコードが必要です。 Androidは、と呼ばれるglibcの流布したバージョンを使用します。通常の機能の大部分は、glibcと一致するシンボル名を持っています。しかし、libcにはstringsに関するいくつかの機能はなく、間違いなくposixがサポートされています。ネイティブライブラリが廃止予定の機能を使用している場合は、libcでサポートされている別の機能を使用して回避策を見つけ、それに応じてライブラリをコーディングする必要があります。また

、あなたが指摘rightyとしてあなたはネイティブの世界へのJava(Androidアプリ/ fwk)(C++)をインタフェースするNDKを使用する必要があります。

これは、Android(アンドロイド移植)上でネイティブライブラリをコンパイルする私の経験ではかなり簡単に聞こえるけど、伝統的に非常に時間がsucessesの保証なしで消費してきました。

+0

あなたの答えをありがとう。実際に私はサードパーティ製のライブラリを移植することを始められません。私はクラスを使用するとすぐコンパイルするための単純なhello-world-likeテストを取得することさえできないからです。最初のステップは、ネイティブのC++テストクラスを作成し、それをjniコールバックCファイルで使用します。それがコンパイルされるかどうかを確認するだけです。 – user745189

0

error: expected '=', ',', ';', 'asm' or '__ attribute __' before 'class'

クラシックケース ';'クラスキーワードの前に?想像してみてください

int functionname(int p) 
class X { } ; 

これはあなたのコンパイラのメッセージに非常に簡単につながります。 )あなたのコンパイルエラーについて

+0

これは私が最初に考えたことですが、私はチェックしました。これは構文エラーではありません – user745189

1

、あなたのように思える。共通の複雑な要因は、それが実際

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

のように見え、エラーが/ someheader.h /または任意の再帰的にインクルードされるファイル内の最後の宣言であるときであります最初に "second.c"と呼ばれ、後で "second.cpp"という名前に変更されましたが、オブジェクトファイルにはまだ "second.c"という名前が付いていますので、コンパイル(bdk-build)/cygdrive/c/android-ndk-r5c/samples/two-libs/obj/local/armeabi/objs/twolib-second /ディレクトリの* .dファイル

0

実行:

ndk-build clean 

Android.mkを間違って変更すると、構成を修正してもビルドが失敗する可能性があります。

これはOPが意味するものだと思いますon this comment

0

編集Android.mk

LOCAL_SRC_FILESのインスタンスを変更し、各ラインのbegginningから./を除去します。

関連する問題