一次调用动态库时出现问题的解决历程
来源:互联网 发布:java封装类例子 编辑:程序博客网 时间:2024/06/05 07:44
在调用库的时候遇到“undefined reference to `showc()'”是经常的事情,大部分情况都是因为没有指定库所在的路径导致的,因此,一般情况下,通过在链接生成可执行的文件的时候,加上“-L路径 -l库名”都可以解决问题。
但是,前几天遇到的问题,通过上述方式却无法解决。为了更好的描述,我简化了问题,使用下面的简单例子,列一下所用到的文件,如下:
makefile如下:
通过makefile,可以得到要生成的库:libshowc.so
下面是调用库的代码
调用库的源文件的makefile如下:
为了更具有一般性,我把调用库的源文件放到库所在目录的子目录,因此添加的库文件目录都是父目录。
文件路径如下(当前目录为库所在目录):
[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修改如下:
编译、链接,如下:
[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]$
但是,前几天遇到的问题,通过上述方式却无法解决。为了更好的描述,我简化了问题,使用下面的简单例子,列一下所用到的文件,如下:
/****************************************************************** * @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 -fPICCOMBIN=$(CC) -o COMLIB=$(CC) -shared -oTARGET=libshowc.soall:${TARGET} clean.SUFFIXES: .cpp .c .o .h${TARGET}:${OBJ}$(COMLIB) $@ $^.c.o:$(CC) -c $*.cclean: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++ -fPICCOMBIN=$(CC) -o COMLIB=$(CC) -shared -oLIB=-L../ -lshowcINCL=-I../TARGET=mainall:${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]$
1 0
- 一次调用动态库时出现问题的解决历程
- 解决导出的MFC扩展动态库在调用时出现Debug Assertion Failed错误的问题
- 解决mingw动态库在vs下调用 release版本中会出现的奇怪问题
- 一次线上游戏卡死的解决历程
- node ffi调用C、C++动态库出现的问题
- struts2 使用动态调用时出现的问题
- Keil 工程出现 error: #757: variable "uint32_t" is not a type name的一次纠错历程(最后没解决)
- 一次软件工程作业:关于C与C++中互相调用动态链接库的问题
- 解决pandas调用scipy时缺少动态运行库的问题
- c++调用dll动态链接库历程
- 记一次发布网站80端口无法访问的解决历程
- 一次手机问题的解决
- 动态库动态调用WEbservice的问题!
- .net 调用css/javascipt出现的问题及解决
- ANDROID Recycleview notifyDataSetChanged()方法调用出现IllegalStateException 问题的解决
- 关于32位和64位部署出现C#调用动态库DLL不成功的问题
- java用jni调用dll动态库出现Can't find dependent libraries问题的解决方法
- 一次调用ACTIVEX控件中出现的问题.不可访问构建函数.
- IOS多线程
- BeanFactory与ApplicationContext【Spring】
- 一段失败的代码 inotify的使用
- 支持老版本IE的3种解决方案
- 八皇后问题
- 一次调用动态库时出现问题的解决历程
- C++中delete, new以及new [], delete[]操作符内幕
- 我的太极拳学习历程
- block学习
- Server对象 HttpUtility.UrlDecode |UrlEncode |HtmlEncode
- Zoj 2562 More Divisors (反素数)
- 程序员必看的十大电影
- workQPanic: Kernel work queue overflow
- warden容器源码解析