2011-08-27 14 views
5

Cでライブラリにリンクしているプログラムを作成し、そのライブラリの関数を呼び出すことができます。Androidのダイナミックリンクライブラリでメインプログラムのシンボルを解決できない

[email protected]:/data/local/tmp # ./helloworld          
link_image[1966]: 637 could not load needed library 'libhello.so' for './helloworld' (reloc_library[1315]: 637 cannot locate 'crossfunction'...) CANNOT LINK EXECUTABLE 

コードは、2つのCファイルである、と私はまた、Makefileを含める:そのライブラリは、メインプログラムから関数を呼び出す場合はエラーが発生します。 hello.cはmain.c(メインプログラム)によって呼び出されるhello関数を保持するライブラリです。関数helloは関数crossfunctionを呼び出そうとし、アンドロイドでは機能しません(Linuxでは完全にうまくいきます)。私はアンドロイドリンカの疑いがありますが、これまでのところ証明はありません(https://android.googlesource.com/platform/bionic/+/froyo-release/linker/README.TXTを参照してください)。

もう1つのヒントは、libhello.soファイルのcrossfunctionのreadelf出力にNOTYPEを割り当てることです。下記を参照してください。

  5: 00000000  0 NOTYPE GLOBAL DEFAULT UND crossfunction 

コンパイラフラグまたはリンカフラグのヒントはありますか?私はここアンドロイドNDK https://github.com/nitomartinez/agcc

とAGCCラッパーを使用してコンパイルするに

:::::::::::::: 
main.c 
:::::::::::::: 
#include <stdio.h> 
extern void hello(const char* name); 
int main(void) { 
    hello("World!"); 
} 

void crossfunction(void) { 
    printf("This is called from the library\n"); 
} 
:::::::::::::: 
hello.c 
:::::::::::::: 
#include <stdio.h> 
extern void crossfunction(void); 
static char *s;  
void hello(const char* name) { 
    s = "my second name"; 
    printf("Hello %s %s!\n", s, name); 
    crossfunction(); 
} 

はMakefileのです:

OBJECTS=main.o 
LIB=libhello.so 
LIBOBJ=hello.o 
TARGET=helloworld 
TARGETDIR=/data/local/tmp 
CC=agcc 

.PHONY: all install run clean distclean 

all: $(TARGET) $(LIB) 

hello.o: hello.c Makefile 
    $(CC) $(CFLAGS) -c -o hello.o hello.c 

$(TARGET): $(OBJECTS) $(LIB) Makefile 
    $(CC) -Wl,-rpath=$(TARGETDIR) -lhello -L . -o $(TARGET) $(OBJECTS) 

$(LIB): $(LIBOBJ) Makefile 
    $(CC) -shared -o $(LIB) $(LIBOBJ) 

install: $(TARGET) 
    adb push $(TARGET) $(TARGETDIR)/$(TARGET) 
    adb push $(LIB) $(TARGETDIR)/$(LIB) 

run: install 
    adb shell "export LD_LIBRARY_PATH=$(TARGETDIR); $(TARGETDIR)/$(TARGET) " 

私はreadelfがビットを見ていたが、私は実質的な差異は認められませんでした.dynsym、.rel.plt、.symtabセクションにあります。 helloworldの

Relocation section '.rel.plt' at offset 0x33c contains 3 entries: 
Offset  Info Type   Sym.Value Sym. Name 
0000954c 00000416 R_ARM_JUMP_SLOT 00008368 hello 
00009550 00000516 R_ARM_JUMP_SLOT 00008374 puts 
00009554 00000816 R_ARM_JUMP_SLOT 00008380 __libc_init 

Symbol table '.dynsym' contains 16 entries: 
    Num: Value Size Type Bind Vis  Ndx Name 
    0: 00000000  0 NOTYPE LOCAL DEFAULT UND 
    1: 000083b0 32 FUNC GLOBAL DEFAULT 7 crossfunction 
    2: 00008450  0 NOTYPE GLOBAL DEFAULT ABS __exidx_end 
    3: 00009558  0 NOTYPE GLOBAL DEFAULT ABS _bss_end__ 
    4: 00008368  0 FUNC GLOBAL DEFAULT UND hello 
    5: 00008374  0 FUNC GLOBAL DEFAULT UND puts 
... 
Symbol table '.symtab' contains 62 entries: 
    Num: Value Size Type Bind Vis  Ndx Name 
... 
    41: 000083b0 32 FUNC GLOBAL DEFAULT 7 crossfunction 
    42: 00008450  0 NOTYPE GLOBAL DEFAULT ABS __exidx_end 
    43: 00009558  0 NOTYPE GLOBAL DEFAULT ABS _bss_end__ 
    44: 00008368  0 FUNC GLOBAL DEFAULT UND hello 
    45: 00008374  0 FUNC GLOBAL DEFAULT UND puts 
... 
    55: 00008390 32 FUNC GLOBAL DEFAULT 7 main 
... 

そしてlibhello.so

Relocation section '.rel.plt' at offset 0xae8 contains 7 entries: 
Offset  Info Type   Sym.Value Sym. Name 
000032cc 00000516 R_ARM_JUMP_SLOT 00000000 crossfunction 
000032d0 00000616 R_ARM_JUMP_SLOT 00000000 printf 
000032d4 00000f16 R_ARM_JUMP_SLOT 00000000 __cxa_begin_cleanup 
000032d8 00001516 R_ARM_JUMP_SLOT 00000000 memcpy 
000032dc 00001f16 R_ARM_JUMP_SLOT 00000000 abort 
... 

Symbol table '.dynsym' contains 64 entries: 
    Num: Value Size Type Bind Vis  Ndx Name 
    0: 00000000  0 NOTYPE LOCAL DEFAULT UND 
... 
    5: 00000000  0 NOTYPE GLOBAL DEFAULT UND crossfunction 
    6: 00000000  0 FUNC GLOBAL DEFAULT UND printf 
... 
    19: 00000b88 100 FUNC GLOBAL DEFAULT 7 hello 
    21: 00000000  0 FUNC GLOBAL DEFAULT UND memcpy 
... 

Symbol table '.symtab' contains 138 entries: 
    Num: Value Size Type Bind Vis  Ndx Name 
    25: 00000000  0 FILE LOCAL DEFAULT ABS hello.c 
    79: 00000000  0 NOTYPE GLOBAL DEFAULT UND crossfunction 
    80: 00000000  0 FUNC GLOBAL DEFAULT UND printf 

答えて

3

用については

バージョン2.0からAndroidのはRTLD_LOCAL共有ライブラリのセマンティクスに従います。ライブラリー内のシンボルが、後でロードされるライブラリーで使用できないことを意味します。メインプログラムを.soライブラリに変換し、それをlibhelloworld.soに明示的にリンクする必要があります。詳細については、this threadを参照してください。

AndroidダイナミックリンカーはLinuxとは異なります。さまざまなバージョンのエミュレータでアプリをテストしてください(Api 3以降)。

+0

それを確認してくれてありがとう、私は何らかの方法でそれを疑った。スレッドを指摘してくれてありがとう。 – Nito

関連する問題