linux下动态链接库函数找不到

hhll26 2010-10-28 12:17:05
我自己产生了一个动态链接库,在编译主程序时,库可以找到,但是库里的函数报错 undefined reference to 函数名。

针对这个动态库,比如我的函数名字叫test,我用命令nm 去看这个动态库,里面没有看到test这个东西,是不是说明库产生的有问题?

如何可以确定问题出在哪里呢?

...全文
960 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
weifirst118 2010-10-29
  • 打赏
  • 举报
回复
C++与C混用的时候
一定要将被C引用的C++部分用extern "C"引起来
justkk 2010-10-29
  • 打赏
  • 举报
回复
试试extern "C" {int csdnso_main(int argc, char *argv[]);}
hhll26 2010-10-29
  • 打赏
  • 举报
回复
justkk,你说的很对,

函数声明及定义,我都添加了extern "C",so库编译成功了,用nm查看,显示的名称果然与源程序中的名称一致。

但是还有个问题,就是编译主程序时,遇到下面的出错信息,好像是关于头文件的:

main_menu.h:1: error: expected identifier or ‘(’ before string constant

我的main_menu.h头文件里,是这样写的:

extern "C"
{
int csdnso_main(int argc, char *argv[]);
}
justkk 2010-10-29
  • 打赏
  • 举报
回复
添加extern "C"时,函数声明及定义都要一起添加
使用nm 查看,如果显示的名称与源程序中的名称一致,就表明添加extern "C"了..
hhll26 2010-10-29
  • 打赏
  • 举报
回复
另外,有无办法查看so文件中,所包含的源程序中,是否已经用extern "C"引起来了?
hhll26 2010-10-29
  • 打赏
  • 举报
回复
你的意思是在用g++编译so库的时候,需要把所有的c++代码用extern "C"引起来?

如果我的库是好几个cpp文件组成的,每个文件里都要这样做吗?

我试了一下,在库代码里的主函数,就是将被外面调用的函数外面用extern "C"引起来,编译时出错说:

main_menu.h: In function ‘int csdnso_main(int,char**)’:
main_menu.h:1: error: previous declaration of ‘int csdnso_main(int, char**)’ with ‘C++’ linkage
main_menu.cpp:6: error: conflicts with new declaration with ‘C’ linkage
make: *** [main_menu.o] Error 1

我猜是不是我的g++编译器已经自动做了这一步了?我的编译器也是平台公司提供的,aaa-linux-g++.

rabbii 2010-10-28
  • 打赏
  • 举报
回复
针对这个动态库,比如我的函数名字叫test,我用命令nm 去看这个动态库,里面没有看到test这个东西,是不是说明库产生的有问题?
--------
感觉是库的问题吧,你编译主程序加库了吗?
库很复杂吗?
xiaocai0001 2010-10-28
  • 打赏
  • 举报
回复
C++与C混用的时候
一定要将被C引用的C++部分用extern "C"引起来

否则链接时,C程序是不识别C++的库的.
justkk 2010-10-28
  • 打赏
  • 举报
回复
是g++比gcc严格
用静态库一样也有这个问题吧?
hhll26 2010-10-28
  • 打赏
  • 举报
回复
即使可以,也最好不要这么干..

但是原来的工程比较大,而且是平台公司提供的,我看他们的程序这样编译什么的,都没有问题。

我刚才把主程序的编译器改成g++,出现了很多原来没有的编译错误,不知道为什么,是不是g++比gcc严格?

如果不得不这么干,上面的so的函数找不到的问题,有办法解决吗?还是只能用静态库了?
justkk 2010-10-28
  • 打赏
  • 举报
回复
即使可以,也最好不要这么干..
hhll26 2010-10-28
  • 打赏
  • 举报
回复
查了一下,你说的是对的,我的库是g++编译的,主程序是gcc编译的。

请问,一个工程中,应该可以有的用gcc编译,有的用g++编译,并且我原来的工程中,就是有的目录下是gcc编译,有的是g++编译,也是可以正常编译和运行的。为什么这里不行呢?

不过,有点不同的是,原来的工程中,没有用到so文件。

justkk 2010-10-28
  • 打赏
  • 举报
回复
那就是上面说的extern "C"了
估计你的库是g++编译的,你主程序是gcc编译的??
hhll26 2010-10-28
  • 打赏
  • 举报
回复
我看了一些ko文件,用nm看的话,出现的就是函数名字,没有一些前缀后缀的。

so库文件可否也做成这样?就不会出现找不到的问题了?

hhll26 2010-10-28
  • 打赏
  • 举报
回复
这里有个问题,我库的编译环境和主程序的不是完全一样的。

如果是这个导致的,请问什么选项可能导致问题呢?
justkk 2010-10-28
  • 打赏
  • 举报
回复
库没有问题啊
c++编译时,对函数名称做了修改,根据入参、返回值啥的,在源名称上加了一些前缀后缀的

你用同样的方式来编译动态库及主程序,应该是可以识别的。
rabbii 2010-10-28
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 hhll26 的回复:]
编译主程序加了库,-L加了路径,-l指明了库名,它没有报找不到库的信息。

是C++编译的吧
这样试试
extern "C" {

另外,这个库,如果单独编译成可执行程序,是没有问题的。我的意思应该不是这个问题吧?编译可执行程序和库都是用的g++
[/Quote]
既然有库的代码,就看下里面有没有函数啊……

你不会没加头文件吧。
hhll26 2010-10-28
  • 打赏
  • 举报
回复
我再仔细说明一下。

我的库中的主函数,就是希望被外面调用的函数名为 csdnso_main, 编译成so库后,用以下命令查看的结果分别是

# objdump -t libmain_menu.so | grep csdn
00005360 g F .text 000000e8 _Z11csdnso_mainiPPc

# nm libmain_menu.so | grep csdn
00005360 T _Z11csdnso_mainiPPc

这是否说明我产生的库有问题?
justkk 2010-10-28
  • 打赏
  • 举报
回复
那就是库里没有你调用的那个函数..
hhll26 2010-10-28
  • 打赏
  • 举报
回复
编译主程序加了库,-L加了路径,-l指明了库名,它没有报找不到库的信息。

是C++编译的吧
这样试试
extern "C" {

另外,这个库,如果单独编译成可执行程序,是没有问题的。我的意思应该不是这个问题吧?编译可执行程序和库都是用的g++
加载更多回复(1)

23,110

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧