Tôi có thể tạo thành công chương trình trong C liên kết đến thư viện và có thể gọi các chức năng của thư viện đó. Nếu thư viện đó gọi một hàm từ chương trình chính, lỗi sẽ phát sinh:Thư viện liên kết động Android không thể giải quyết các biểu tượng của chương trình chính
[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
Mã nằm trong hai tệp C và tôi cũng bao gồm Makefile. hello.c là thư viện chứa hàm hello được gọi bởi main.c (chương trình chính). Hàm hello cố gắng gọi hàm crossfunction và không hoạt động trong android (trong Linux nó hoạt động hoàn toàn tốt). Tôi nghi ngờ từ liên kết android, nhưng không có bằng chứng cho đến nay (xin vui lòng xem https://android.googlesource.com/platform/bionic/+/froyo-release/linker/README.TXT).
Một gợi ý tốt khác có thể là gán NOTYPE trong đầu ra đọc cho giao diện trong tệp libhello.so. Vui lòng xem bên dưới.
5: 00000000 0 NOTYPE GLOBAL DEFAULT UND crossfunction
Bất kỳ gợi ý nào có thể trong cờ trình biên dịch hoặc cờ liên kết?
::::::::::::::
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();
}
Để biên dịch tôi sử dụng wrapper AGCC với ndk android https://github.com/nitomartinez/agcc
Đây là 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) "
tôi đã có một cái nhìn tại các bit readelf, nhưng tôi thấy không có sự khác biệt đáng kể trong các phần .dynsym, .rel.plt và .symtab.
Đối 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
...
Và đối với 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
Cảm ơn bạn đã xác nhận điều đó, tôi nghi ngờ rằng theo một cách nào đó. Cảm ơn bạn đã chỉ ra chuỗi đó. – Nito