Android - 动态库双向依赖解决方法
问题:
昨天调试一个CA库link失败的问题:ca厂商一般提供的都是静态ca库,这样子你直接将其与
你的库link在一起即可使用,但由于apk在ndk中编译器:android-ndk-r6b\arm-linux-androideabi-4.4.3
而ca库使用hisi编译器:arm-eabi-4.4.0_hisi 两者使用的编译不同,所以需要在linux android环境
下将ca静态库打包成动态库,而且用户实现的ca函数将会link失败,生成的动态库将在ndk中使用。
下面是一个简单的测试例子,用于说明一下如何做到相互依赖而编译生成动态库的方法
1、首先编译生成动态库
首先定义头文件:test.h
1. <span style="font-size:16px;">#ifndef XXX_TEST_H___
2. #define XXX_TEST_H___
3.
4. /* 由link的库实现 */
5. extern void testA();
6. extern void testB();
7.
8. /* 由本身库实现而由外部调用 */
9. extern void testC();
10. extern void testD();
11.
12. struct AAInte易做图ce{
13. void (*testA)();
14. void (*testB)();
15. };
16.
17. extern void setInte易做图ce(struct AAInte易做图ce *cb);
18.
19. #endif /* XXX_TEST_H___ */
20. </span>
然后实现文件:testA.c
1. <span style="font-size:16px;">#include <assert.h>
2. #include <stdlib.h>
3. #include <string.h>
4. #include <cutils/log.h>
5. #include "test.h"
6.
7. static struct AAInte易做图ce g_aa_inte易做图ce ;
8.
9. /* 由link的库实现 */
10. extern void testA(){
11. g_aa_inte易做图ce.testA();
12. }
13.
14. extern void testB(){
15. g_aa_inte易做图ce.testB();
16. }
17.
18. extern void testCall(){
19. LOGI("testCall 111");
20. testA();
21. LOGI("testCall 222");
22. testB();
23. LOGI("testCall 333");
24. }
25.
26. /* 由本身库实现而由外部调用 */
27. extern void testC(){
28. LOGI("testC call in--->");
29. testCall();
30. LOGI("testC call out<---");
31. }
32.
33. extern void testD(){
34. LOGI("testD call in--->");
35. testCall();
36. LOGI("testD call out<---");
37. }
38.
39. extern void setInte易做图ce(struct AAInte易做图ce *cb){
40. LOGI("setInte易做图ce call in -->");
41. memset((void*)&g_aa_inte易做图ce,0x00,sizeof(g_aa_inte易做图ce));
42. g_aa_inte易做图ce.testA = cb->testA;
43. g_aa_inte易做图ce.testB = cb->testB;
44. LOGI("setInte易做图ce call out <--");
45. }
46. </span>
这里最重要的是利用setInte易做图ce接口解决相互link的问题,这就是本质所在。大家一看就明白了,这也是动态
库导出函数的最好方法,一般使用QueryInte易做图ce及enumInte易做图ce即可,使用结构将
编译方法:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE:= libtestASO
LOCAL_SRC_FILES:= \
testA.c \
LOCAL_SHARED_LIBRARIES := liblog\
LOCAL_C_INCLUDES += \
$(TOP)/frameworks/base/test/testA \
LOCAL_CFLAGS += -D_cplusplus
LOCAL_PRELINK_MODULE := false
include $(BUILD_SHARED_LIBRARY)
2、使用生成的动态库
1. <span style="font-size:16px;">#include <assert.h>
2. #include <stdlib.h>
3. #include <string.h>
4. #include <cutils/log.h>
5. #include <test.h>
6.
7. /* 由link的库实现 */
8. extern void testA(){
9. LOGI("testA call ...");
10. }
11.
12. extern void testB(){
13. LOGI("testB call ...");
14. }
15.
16. int main(void){
17. struct AAInte易做图ce *itf = (struct AAInte易做图ce*)calloc(1,sizeof(struct AAInte易做图ce));
18. itf->testA = testA;
19. itf->testB = testB;
20. setInte易做图ce(itf);
21. www.zzzyk.com
22. testC();
23. testD();
24. return 0;
25. }
26. </span>
ok,知道了如何解决这种相互依赖的方法,解决方法相当解决。。对于这种A需要link B,而B又需要link A的相互关系,这种方法就会起到很好的作用了。
作者:andyhuabing
补充:移动开发 , Android ,