Android - 动态库双向依赖解决方法
2013-07-22 14:47
393 查看
http://blog.csdn.net/andyhuabing/article/details/7668559
问题:
昨天调试一个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
[cpp]
view plaincopyprint?
<span style="font-size: 16px;">#ifndef XXX_TEST_H___
#define XXX_TEST_H___
/* 由link的库实现 */
extern
void testA();
extern
void testB();
/* 由本身库实现而由外部调用 */
extern
void testC();
extern
void testD();
struct AAInterface{
void (*testA)();
void (*testB)();
};
extern
void setInterface(struct AAInterface *cb);
#endif /* XXX_TEST_H___ */
</span>
然后实现文件:testA.c
[cpp]
view plaincopyprint?
<span style="font-size: 16px;">#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <cutils/log.h>
#include "test.h"
static
struct AAInterface g_aa_interface ;
/* 由link的库实现 */
extern
void testA(){
g_aa_interface.testA();
}
extern
void testB(){
g_aa_interface.testB();
}
extern
void testCall(){
LOGI("testCall 111");
testA();
LOGI("testCall 222");
testB();
LOGI("testCall 333");
}
/* 由本身库实现而由外部调用 */
extern
void testC(){
LOGI("testC call in--->");
testCall();
LOGI("testC call out<---");
}
extern
void testD(){
LOGI("testD call in--->");
testCall();
LOGI("testD call out<---");
}
extern
void setInterface(struct AAInterface *cb){
LOGI("setInterface call in -->");
memset((void*)&g_aa_interface,0x00,sizeof(g_aa_interface));
g_aa_interface.testA = cb->testA;
g_aa_interface.testB = cb->testB;
LOGI("setInterface call out <--");
}
</span>
这里最重要的是利用setInterface接口解决相互link的问题,这就是本质所在。大家一看就明白了,这也是动态
库导出函数的最好方法,一般使用QueryInterface及enumInterface即可,使用结构将
编译方法:
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、使用生成的动态库
[cpp]
view plaincopyprint?
<span style="font-size: 16px;">#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <cutils/log.h>
#include <test.h>
/* 由link的库实现 */
extern
void testA(){
LOGI("testA call ...");
}
extern
void testB(){
LOGI("testB call ...");
}
int main(void){
struct AAInterface *itf = (struct AAInterface*)calloc(1,sizeof(struct
AAInterface));
itf->testA = testA;
itf->testB = testB;
setInterface(itf);
testC();
testD();
return 0;
}
</span>
ok,知道了如何解决这种相互依赖的方法,解决方法相当解决。。对于这种A需要link B,而B又需要link A的相互关系,这种方法就会起到很好的作用了。
问题:
昨天调试一个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
[cpp]
view plaincopyprint?
<span style="font-size: 16px;">#ifndef XXX_TEST_H___
#define XXX_TEST_H___
/* 由link的库实现 */
extern
void testA();
extern
void testB();
/* 由本身库实现而由外部调用 */
extern
void testC();
extern
void testD();
struct AAInterface{
void (*testA)();
void (*testB)();
};
extern
void setInterface(struct AAInterface *cb);
#endif /* XXX_TEST_H___ */
</span>
#ifndef XXX_TEST_H___ #define XXX_TEST_H___ /* 由link的库实现 */ extern void testA(); extern void testB(); /* 由本身库实现而由外部调用 */ extern void testC(); extern void testD(); struct AAInterface{ void (*testA)(); void (*testB)(); }; extern void setInterface(struct AAInterface *cb); #endif /* XXX_TEST_H___ */
然后实现文件:testA.c
[cpp]
view plaincopyprint?
<span style="font-size: 16px;">#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <cutils/log.h>
#include "test.h"
static
struct AAInterface g_aa_interface ;
/* 由link的库实现 */
extern
void testA(){
g_aa_interface.testA();
}
extern
void testB(){
g_aa_interface.testB();
}
extern
void testCall(){
LOGI("testCall 111");
testA();
LOGI("testCall 222");
testB();
LOGI("testCall 333");
}
/* 由本身库实现而由外部调用 */
extern
void testC(){
LOGI("testC call in--->");
testCall();
LOGI("testC call out<---");
}
extern
void testD(){
LOGI("testD call in--->");
testCall();
LOGI("testD call out<---");
}
extern
void setInterface(struct AAInterface *cb){
LOGI("setInterface call in -->");
memset((void*)&g_aa_interface,0x00,sizeof(g_aa_interface));
g_aa_interface.testA = cb->testA;
g_aa_interface.testB = cb->testB;
LOGI("setInterface call out <--");
}
</span>
#include <assert.h> #include <stdlib.h> #include <string.h> #include <cutils/log.h> #include "test.h" static struct AAInterface g_aa_interface ; /* 由link的库实现 */ extern void testA(){ g_aa_interface.testA(); } extern void testB(){ g_aa_interface.testB(); } extern void testCall(){ LOGI("testCall 111"); testA(); LOGI("testCall 222"); testB(); LOGI("testCall 333"); } /* 由本身库实现而由外部调用 */ extern void testC(){ LOGI("testC call in--->"); testCall(); LOGI("testC call out<---"); } extern void testD(){ LOGI("testD call in--->"); testCall(); LOGI("testD call out<---"); } extern void setInterface(struct AAInterface *cb){ LOGI("setInterface call in -->"); memset((void*)&g_aa_interface,0x00,sizeof(g_aa_interface)); g_aa_interface.testA = cb->testA; g_aa_interface.testB = cb->testB; LOGI("setInterface call out <--"); }
这里最重要的是利用setInterface接口解决相互link的问题,这就是本质所在。大家一看就明白了,这也是动态
库导出函数的最好方法,一般使用QueryInterface及enumInterface即可,使用结构将
编译方法:
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、使用生成的动态库
[cpp]
view plaincopyprint?
<span style="font-size: 16px;">#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <cutils/log.h>
#include <test.h>
/* 由link的库实现 */
extern
void testA(){
LOGI("testA call ...");
}
extern
void testB(){
LOGI("testB call ...");
}
int main(void){
struct AAInterface *itf = (struct AAInterface*)calloc(1,sizeof(struct
AAInterface));
itf->testA = testA;
itf->testB = testB;
setInterface(itf);
testC();
testD();
return 0;
}
</span>
#include <assert.h> #include <stdlib.h> #include <string.h> #include <cutils/log.h> #include <test.h> /* 由link的库实现 */ extern void testA(){ LOGI("testA call ..."); } extern void testB(){ LOGI("testB call ..."); } int main(void){ struct AAInterface *itf = (struct AAInterface*)calloc(1,sizeof(struct AAInterface)); itf->testA = testA; itf->testB = testB; setInterface(itf); testC(); testD(); return 0; }
ok,知道了如何解决这种相互依赖的方法,解决方法相当解决。。对于这种A需要link B,而B又需要link A的相互关系,这种方法就会起到很好的作用了。
相关文章推荐
- Android - 动态库双向依赖解决方法
- Android - 动态库双向依赖解决方法
- 【Android笔记】Android引用第三方依赖包library报错解决方法
- Android多项目依赖在Eclipse中无法关联源代码的问题解决 Ctril 点不进去的解决方法
- Android 65535问题解决方法之不分包只删除jar包无用依赖
- 生成动态库so的方法|解决NDK r5b引用静态库失效的问题|在NDK的Nactive代码中使用Android Log的方法|生成Native java头文件
- Android依赖库版本冲突的一个解决方法
- Android程序 依赖库引用Gson 报java.lang.NoClassDefFoundError: com/google/gson/Gson 解决方法
- Android程序 依赖库引用Gson 报java.lang.NoClassDefFoundError: com/google/gson/Gson 解决方法
- Android多项目依赖在Eclipse中无法关联源代码的问题解决 Ctril 点不进去的解决方法
- 【解决方法】android拍照获得的图片太小
- Android 图片加载Bit地图 OOM异常解决方法
- android 自定义键盘碰到的问题及解决方法
- Android遇到内存溢出(Out Of Memory)BUG的经验与解决方法
- ANDROID Recycleview notifyDataSetChanged()方法调用出现IllegalStateException 问题的解决
- Android中的Notification直接实例化方法deprecated的解决
- Android ExpandableListView长按事件解决方法一
- 最新Android 出现Please ensure that adb is correctly located at问题的解决方法
- Android应用插件式开发解决方法
- 将android工程导入eclipse中找不到 R文件的解决方法