一次调用动态库时出现问题的解决历程

在调用库的时候遇到“undefined reference to `showc()'”是经常的事情,大部分情况都是因为没有指定库所在的路径导致的,因此,一般情况下,通过在链接生成可执行的文件的时候,加上“-L路径 -l库名”都可以解决问题。
但是,前几天遇到的问题,通过上述方式却无法解决。为了更好的描述,我简化了问题,使用下面的简单例子,列一下所用到的文件,如下:
 /******************************************************************
 *  @file       showc.h
 *  @version    v1.0 
 *  @author     ymm 
 *  @date       2014/2/14 18:46:57
 *  @brief      c 语言中的show实现
 *  @history      
 *  1、2014/2/14 18:46:57  author ymm    初步完成
 ******************************************************************/
#ifndef __SHOWC_H__
#define __SHOWC_H__
void showc();
#endif


 /******************************************************************
 *  @file       showc.c
 *  @version    v1.0 
 *  @author     ymm 
 *  @date       2014/2/14 18:46:57
 *  @brief      c 语言中的show实现
 *  @history      
 *  1、2014/2/14 18:46:57  author ymm    初步完成
 ******************************************************************/
#include "showc.h"
#include <stdio.h>
void showc()
{
    printf("in c,in fun %s\n",__FUNCTION__);
}



makefile如下:

OBJ=showc.o 
CC=gcc -fPIC
COMBIN=$(CC) -o 
COMLIB=$(CC) -shared -o


TARGET=libshowc.so
all:${TARGET} clean


.SUFFIXES: .cpp .c .o .h
${TARGET}:${OBJ}
	$(COMLIB) $@ $^


.c.o:
	$(CC) -c $*.c
clean:
	rm -f *.o core.*



通过makefile,可以得到要生成的库:libshowc.so


下面是调用库的代码
 /******************************************************************
 *  @file       main.cpp
 *  @version    v1.0 
 *  @author     ymm 
 *  @date       2014/2/14 18:52:39
 *  @brief      c++调用库的测试函数
 *  @history      
 *  1、2014/2/14 18:52:39  author ymm    初步完成
 ******************************************************************/
#include <iostream>
//extern "C"
//{
#include "showc.h"
//}
using namespace std;
int main()
{
    showc();
    return 0;
}


调用库的源文件的makefile如下:


OBJ=main.o 


CC=g++ -fPIC
COMBIN=$(CC) -o 
COMLIB=$(CC) -shared -o
LIB=-L../ -lshowc
INCL=-I../


TARGET=main
all:${TARGET} clean


.SUFFIXES: .cpp .c .o .h
${TARGET}:${OBJ}
	$(COMBIN) $@ $^ ${LIB}


.cpp.o:
	$(CC) -c $*.cpp ${INCL}
clean:
	rm -f *.o core.*




为了更具有一般性,我把调用库的源文件放到库所在目录的子目录,因此添加的库文件目录都是父目录。
文件路径如下(当前目录为库所在目录):
[billing_dx@bmcs1 library]$ls -R
.:
call  libshowc.so  makefile  showc.c  showc.h


./call:
main.cpp  makefile
[billing_dx@bmcs1 library]$


库好像添加成功了,但是,编译的时候,出现问题,编译情况如下:
[billing_dx@bmcs1 call]$make clean;
rm -f *.o core.*
[billing_dx@bmcs1 call]$make
g++ -fPIC -c main.cpp -I../ #编译
g++ -fPIC -o  main main.o -L../ -lshowc #连接
main.o: In function `main':
main.cpp:(.text+0x5): undefined reference to `showc()'
collect2: ld returned 1 exit status
make: *** [main] Error 1
[billing_dx@bmcs1 call]$


编译通过,说明编译的时候找到了头文件“showc.h”,但是链接的时候,还是找不到函数。
后来,同事提示了一下,生成的库是不是c语言编写的库,因为c++和c在对函数处理后的命名是不同,c++需要添加许多无用的内容。因为是c++调用的是c语言的库,因此需要告诉程序,库的文件类型。
于是,在引用库所对应的头文件的时候,添加extern "C",main.cpp修改如下:
#include <iostream>
extern "C"
{
    #include "showc.h"
}
using namespace std;



编译、链接,如下:
[billing_dx@bmcs1 call]$make
g++ -fPIC -c main.cpp -I../
g++ -fPIC -o  main main.o -L../ -lshowc
rm -f *.o core.*
[billing_dx@bmcs1 call]$


虽然编译通过了,但是,当运行的时候,还是会出现问题:
[billing_dx@bmcs1 call]$main
main: error while loading shared libraries: libshowc.so: cannot open shared object file: No such file or directory
[billing_dx@bmcs1 call]$


似乎还是找不到库,为什么会这样呢?
因为,编译的时候,寻找库的方式是通过链接的时候指定的路径来找的,因为我在makefile中定义了“LIB=-L../ -lshowc”,因此是可以编译通过的。但是,运行的时候,却是通过查看环境变量“LD_LIBRARY_PATH”来寻找动态库的,因为新生成的动态库所在的路径不在该环境变量中,因此,运行的时候,会出现找不到库的错误。
为了运行,我们可以临时修改环境变量“LD_LIBRARY_PATH”的值。
进入到库所在的目录,如下:
[billing_dx@bmcs1 library]$ls #进入到库所在的目录
call  libshowc.so  makefile  showc.c  showc.h
[billing_dx@bmcs1 library]$export LD_LIBRARY_PATH=$(pwd):$LD_LIBRARY_PATH   #环境变量中添加库所在的目录
[billing_dx@bmcs1 library]$cd call/ #进入调用库的目录
[billing_dx@bmcs1 call]$ls #查看生成的可执行文件
main  main.cpp  makefile
[billing_dx@bmcs1 call]$main #成功执行
in c,in fun showc
[billing_dx@bmcs1 call]$
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值