您的位置:首页 > 移动开发 > Android开发

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> 

#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的相互关系,这种方法就会起到很好的作用了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐