2011-08-27 14 views
5

Bir kütüphaneye bağlanan ve bu kütüphanenin işlevlerini çağırabilen bir C programını başarılı bir şekilde oluşturabilirim.Android dinamik bağlantı kütüphanesi ana programın simgelerini çözemedi

[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 

kod iki C dosyalarında, ve ben de Makefile şunlardır: o kütüphane ana programdan bir işlevi çağırırsa bir hata ortaya çıkar. hello.c, main.c (ana program) tarafından çağrılan fonksiyonu merhaba tutan kütüphanedir. Merhaba fonksiyonu, işlev çapraz fonksiyonunu çağırmaya çalışır ve bu da androidde işe yaramaz (Linux'ta gayet iyi çalışır). Ben android linker şüpheli, ama şu ana kadar hiç kanıtı yok (bkz. https://android.googlesource.com/platform/bionic/+/froyo-release/linker/README.TXT).

Bir başka iyi ipucu, libhello.so dosyasındaki çapraz işlev için kendi çıkışında bulunan NOTYPE ataması olabilir. Lütfen aşağıya bakın.

  5: 00000000  0 NOTYPE GLOBAL DEFAULT UND crossfunction 

Derleyici bayraklarında veya bağlayıcı bayraklarında belki de herhangi bir ipucu var mı?

:::::::::::::: 
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(); 
} 

Ben robot NDK İşte https://github.com/nitomartinez/agcc

ile AGCC kapsayıcı kullanabilir derlemek için Makefile geçerli:

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) " 

Ben readelf bit bir göz vardı, ama büyük bir farklılık yoktu bulundu .dynsym, .rel.plt ve .symtab bölümlerinde.

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 
... 

için

Ve yönelik libhello.so Android RTLD_LOCAL paylaşılan kütüphane anlamsallıktadır sürüm 2.0 itibaren

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 

cevap

3

. Kütüphanelerdeki sembollerin daha sonra yüklenen kütüphaneler için mevcut olmadığı anlamına gelir. Ana programınızı bir .so kütüphanesine dönüştürmeniz ve bunu libhelloworld.so'ya açıkça bağlamanız gerekir. Daha fazla bilgi için this thread'a bakın.

Android dinamik bağlantı aracının Linux sürümünden farklı olduğunu unutmayın. Mekanizmaları zaman içinde değiştikçe, uygulamalarınızı farklı sürümlerdeki emülatörlerde (Api 3'ten başlayarak) test ettiğinizden emin olun.

+0

Bunu onayladığın için, bir şekilde şüpheliyim. Ayrıca iş parçacığı için teşekkürler. – Nito