linux 动态库

来源:互联网 发布:有哪些的网络推广方法 编辑:程序博客网 时间:2024/05/21 17:48

netra平台下对动态库的编译调用

一、问题描述

在一个项目中,需要调用共享平台组提供的多个动态库。在以往的项目中没有调用过动态库的经验,而NB设备中原本调用库大多是静态库,仅有的动态库也是c标准库或pthread库这些编译器提供的库,因此没有经验可以参考。在开发过程中,遇到了许多难题,这里进行一下记录和总结。

二、解决过程

首先,描述一下运行环境。在虚拟机上安装了交叉编译工具,设备的系统代码都是在虚拟机上编译链接打包的,为了使动态库也能够在设备上运行,需要在虚拟机上使用交叉编译工具来编译动态库。编译完成后,在写一个测试程序简单测试动态库的可用性。最后,在设备的系统中添加对动态库的调用,实现想要的功能。

第二是要解决的问题是交叉编译工具是否支持动态库的编译,在项目执行过程中,因为交叉编译工具版本问题,不支持编译动态库,导致项目延后了一段时间。为了验证交叉编译工具是否支持动态库,可以编写一个简单动态库和简单测试程序来实验。

//Mydll.cpp

#include "stdio.h"

 

void print()

{

    printf("i am dll\n");

}

 

//Mytest.cpp

#include "stdio.h"

 

externvoid print();

int main()

{

    print();

    return0;

}

 

         编写makefile来生成动态库和测试程序:

        

CC=gcc

SOFLAGS=-shared -fPIC -o2

 

PROGS= testmain

SO= test.so

 

all: ${PROGS}

 

testmain:$(SO)

$(CC) -o $@ $^ mytest.cpp

 

$(SO):

$(CC)$(SOFLAGS) -o$(SO) mydll.cpp

 

clean:

    rm -f$(PROGS)

    rm -f$(SO)

 

         test.so拷贝到/lib/目录下,系统在加载库时才能找到动态库的位置。拷贝后,进入testmain所在文件夹,输入./testmain执行程序,输出 “I am dll”则表示成功。另外要注意的是,如果动态库依赖于某个库,那么在编译动态库和测试程序时都要将这个库链接上,否则在编译时不会出错,在运行时会出现异常,而且使用core dump文件也很难排查出来到底是哪里出了问题。如将makefile文件改成如下所示:

        

CC=gcc

SOFLAGS=-shared -fPIC -o2

 

LIB = -lpthread

PROGS= testmain

SO= test.so

 

all: ${PROGS}

 

testmain:$(SO)

$(CC) -o $@ $^ mytest.cpp

 

$(SO):

$(CC)$(SOFLAGS) $(LIB) -o$(SO) mydll.cpp

 

clean:

    rm -f$(PROGS)

    rm -f$(SO)

 

         在编译时不会报错,但是在运行时会出现异常:

         使用gdb查看core文件,结果如下:

         显示的错误信息是找不到test.so,程序终止在_getopt_internal(),但是可以确定test.so已经拷贝到响应目录。因此,编译可执行程序时,要将动态库依赖的库也链接上。

         以上是编译运行动态库和测试程序的全过程。在确认交叉编译工具正常之后,使用交叉编译工具编译需要的库,并编写对应的测试文件,可以正常运行后就可以将动态库的接口集成到设备的系统中。但是,这时遇到一个问题,测试程序可以正常运行而集成到设备的环境后就无法运行。在经过一番排查后,发现动态库依赖一个hpr库,而设备的系统中原先就已经将hpr库的代码编译到静态库中,并且加载到程序里了。这是,在动态库调用hpr库对应函数时,动态库实际调用的是编译到系统中的hpr库接口,两个hpr库版本不一致时会出现问题。这个问题非常隐蔽,在编译过程中也不会被检查到,只有在实际运行时才会发现。解决问题的办法是将其中一个hpr库屏蔽掉。由于系统中不会使用到静态库的接口,所以选择将静态库屏蔽掉,这样就不会造成调用接口出错的问题了。

三、问题总结

         1、首先要确认交叉编译工具是否能够正常工作,编译一个动态库和一个测试程序实验一下。注意编译测试程序时要连接动态库所有依赖的动态库。

         2、可执行程序代码中的接口与动态库依赖的动态库接口不能一样,否则会导致动态库调用接口出错。

0 0
原创粉丝点击