3

私は本当に単純な helloworld.cpp プログラムを持っています

#include <iostream>
using namespace std;
int main ()
{
  cout << "Hello World!";
  return 0;
}

そして、ツールチェーンのクロスコンパイラを使用してAndroid x86用にコンパイルしようとしています:

/Users/me/android-ndk-r8/toolchains/x86-4.4.3/prebuilt/darwin-x86/bin/i686-android-linux-g++ helloworld.cpp -L "/Users/me/android-ndk-r8/sources/cxx-stl/stlport/libs/x86/" -lstlport_static

ただし、エラーが発生します。

helloworld.cpp:2:20: error: iostream: No such file or directory

理由はありますか?

4

3 に答える 3

7

「スタンドアロン ツールチェーン」の下にある、NDK に含まれている documentation.html ファイルを確認します。この方法でコンパイラを呼び出すと、「C++ STL を使用する」ことができなくなると書かれています。ただし、ドキュメントで説明されているように、次のコマンドのようなものを使用して、最初に「カスタマイズされた」ツールチェーン インストールを作成する場合は可能です。

$NDK/build/tools/make-standalone-toolchain.sh --platform=android-8 --install-dir=/tmp/my-android-toolchain --arch=x86

ここで、$NDK は NDK ディレクトリへのパスです。--arch=x86 に注意してください。これは、ツールチェーンが x86 Android 専用に用意されていることを意味します。これにより、STL ヘッダーやフォルダーなど、必要なものが 1 つのディレクトリに準備されます。次に、-lstdc++ を使用して、STL (静的バージョン) に対してリンクできるようにする必要があります。つまり、次のようになります。

/tmp/my-android-toolchain/bin/i686-android-linux-g++ helloworld.cpp -lstdc++

より完全な説明については、NDK のドキュメントを参照してください。

于 2012-06-13T02:08:32.807 に答える
2

NDK のドキュメントは、少なくとも現時点では完全に正確ではありません。実際、ビルド済みのツールチェーンを使用すると、「C++ STL (STLport または GNU libstdc++) を使用することはできません。」と記載されていますが、これは古くなっています。インクルードを使用して小さな hello world プログラムを作成しましたが、同じエラーが発生しました。ただし、独自のツールチェーンを作成しなくても解決できます。これは、構成プロセスにもう 1 つの手順を追加する必要がなく、毎回新しいツールチェーンを作成することなく常に最新の SDK プラットフォームを使用できる場合に便利です。

NDK には、標準 C++ ライブラリのいくつかのバージョン (GAbi++、STLport、および GNU STL) のソース コードが付属しています。各フレーバーには、ビルド済みの共有ライブラリと静的ライブラリも付属しています。以下の例では、stlport を使用します。

インストールされた場所でスタンドアロン ツールチェーンを使用するには、次のようにします。 g++ --sysroot="$NDK_ROOT/platforms/android-19/arch-arm"'

たとえば、これにより、SDK プラットフォーム レベル 19 を使用して OS X システムで ARM をコンパイルするように CXX コンパイラが設定されます。また、使用する場合は、CC、CPP、LD、AR、および RANLIB をエクスポートする必要があります。また、READELF の環境変数も個人的に作成しています。

C++ ライブラリのサポートを追加するには、次のようにします。 lstlport_shared

これにより、実行時に必要になる libstlport_shared.so がリンクされることに注意してください。そのため、APK 構造によっては、上記のコマンドに相対パスを追加してサポートする必要がある場合があります。この単純なケースをテストするだけの場合は、次のようにエミュレーターで実行できます。

adb push a.out /data
adb push $NDK_ROOT/sources/cxx-stl/stlport/libs/armeabi/libstlport_shared.so /data
adb shell
# su
# cd /data
# chmod 777 a.out
# ./a.out

共有ライブラリ パスを処理するという頭痛の種を取り除くために、「-lstlport_shared」を「-lstlport_static」に変更して、C++ ライブラリを静的にリンクすることもできます。NDK Dev Guide で説明されているように、これを行うといくつかの結果が生じます。最大の問題は、スタティック ライブラリが複数の場所でリンクされていることによるものです。これにより、次のことが発生します。- libfoo.so で発生した例外は、libbar.so でキャッチできません (そして、単にプログラムをクラッシュさせる可能性があります)。- std::cout のバッファリングが正しく機能しない

プログラムの依存関係を確認するための便利なツールである readelf ツールも含まれています。

プログラムに必要なその他の共有ライブラリを確認するには、次を実行します。grep が必要

その他の優れた標準ツール: addr2line - スタック トレース アドレスをコード行に変換 nm - シンボル テーブルを表示 objdump - オブジェクトに関する情報を表示

于 2014-01-03T16:24:41.437 に答える