3

私は2つのファイルを持っています:

lib.c

#include<stdio.h>

void hi() {
  printf("Hi i'm a library function in lib.so\n");
} 

およびmain.c

#include<stdio.h>
#include<dlfcn.h>
/* based on Jeff Scudder's code */
int main() {
  void *SharedObjectFile;
  void (*hi)();

  // Load the shared libary;
  SharedObjectFile = dlopen("./lib.so", RTLD_LAZY);

  // Obtain the address of a function in the shared library.
  ciao = dlsym(SharedObjectFile, "hi");

  // Use the dynamically loaded function.
  (*hi)();

  dlclose(SharedObjectFile);
}

そして、次のコマンドを使用して実行可能ファイルを構築しようとしました:

エクスポート LD_LIBRARY_PATH=pwd

gcc -c -fpic lib.c

gcc -shared -lc -o lib.so lib.o

gcc main.c -ldl

そして、それはかなりうまく機能します。次に、次のコマンドを使用して、プログラムを Android (Nexus One、ARM-v7-0a アーキテクチャ) にエクスポートしようとしました。

エクスポート LD_LIBRARY_PATH=pwd

arm-none-linux-gnueabi-gcc -c -fpic lib.c

arm-none-linux-gnueabi-gcc -shared -lc -o lib.so lib.o

arm-none-linux-gnueabi-gcc main.c -ldl -o メイン

adb push main /system/app

スマートフォンの正しいフォルダーで ./main を実行した結果は次のとおりです。

./メイン: 見つかりません

私のファイルがそこにあるとしても!

クロスコンパイル プロセス中に何か不足していますか? 何か助けはありますか?CodeSourcery のクロスコンパイラを使用していますが、.so ライブラリのない静的プログラムではうまく機能します。ありがとう

編集:Igorが以下に述べているように、それはリンカの問題でした。このコマンドはそれを修正します:

arm-none-linux-gnueabi-gcc -o test main.c -Wl,--dynamic-linker=/system/bin/linker -ldl

私の場合、 /system/lib/ には .so ファイルがあまりないため、他のライブラリが必要です。

4

1 に答える 1

7

「見つかりません」というメッセージは、共有オブジェクトではなく動的リンカーを参照しています。Linux は/lib/ld-linux.so.2(または/lib64/ld-linux-x86-64.so.2x64 の場合) を使用し、Android は を使用し /bin/linkerます。プログラムが使用している動的ローダーを確認できますreadelf -l。たとえば、次のようになります。

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x08048034 0x08048034 0x00100 0x00100 R E 0x4
  INTERP         0x000134 0x08048134 0x08048134 0x00013 0x00013 R   0x1
      [Requesting program interpreter: /lib/ld-linux.so.2]

ld のスイッチで使用するリンカーを指定できますが、--dynamic-linker他にも違いがある可能性があります。たとえば、Android は bionic と呼ばれる簡素化された libc 実装を使用しており、プログラムが依存している機能が欠落しているか、異なる動作をしている可能性があります。

Android 用のプログラムをコンパイルするときは、NDK または別の Android を対象としたツールチェーンを使用する必要があります。Linux カーネルに基づいていますが、違いが大きいため、Linux を対象としたツールチェーンでは十分ではありません。

于 2013-02-18T15:44:38.887 に答える