Chinaunix

标题: Gcc编译出的库无法被Sun ld调用 [打印本页]

作者: lipingtababa    时间: 2008-06-25 13:01
标题: Gcc编译出的库无法被Sun ld调用
我的Berkeley DB是用gcc从源代码编译安装的,生成libdb_cxx.so文件,在编译的时候,我把sun的ld改名为ld.sun,安装了gnu binutil 2.17。

后来我在Solaris上安装了sun studio 12,使用sun的编译器和ld来编译ICe 3.2.1,在ld的时候,报错如下
CC -R /usr/sfw/lib  -z text -mt +p -features=tmplife -xldscope=hidden +w -erroff=hidef,wvarhidenmem,wvarhidemem -m32 -KPIC -g -L../../lib  -o ../../bin/transformdb TransformAnalyzer.o TransformVisitor.o Transformer.o transformdb.o Grammar.o Scanner.o AssignVisitor.o Data.o Error.o Functions.o Exception.o Parser.o Print.o Util.o -lSlice  -lIceXML -L/usr/local/BerkeleyDB.4.5/lib -lFreeze  -lIce -lIceUtil -lpthread -L/usr/local/BerkeleyDB.4.5/lib -ldb_cxx
Undefined symbol                                  first referenced in file

Dbt::~Dbt()                                            Transformer.o
int Db::set_bt_minkey(unsigned)           ../../lib/libFreeze.so
.....

我切换到/usr/local/BerkeleyDB.4.5/lib 目录,发现set_bt_minkey的symbol存在。只是名字有变化。
[root@sunserver:/usr/local/BerkeleyDB.4.5/lib]# nm libdb_cxx.so |grep set_bt_minkey
0002568c T _ZN2Db13set_bt_minkeyEj
00039030 t __bam_set_bt_minkey
[root@sunserver:/usr/local/BerkeleyDB.4.5/lib]#

后来改用sun studio 12编译Berkeley DB,再编译Ice就没这个问题了。

请问各位大虾,出现这个问题的原因是什么?
作者: zszyj    时间: 2008-06-25 15:02
原帖由 lipingtababa 于 2008-6-25 13:01 发表
我的Berkeley DB是用gcc从源代码编译安装的,生成libdb_cxx.so文件,在编译的时候,我把sun的ld改名为ld.sun,安装了gnu binutil 2.17。

后来我在Solaris上安装了sun studio 12,使用sun的编译器和ld来编译IC ...

是用C++编译器编译出来的吧, 试试在函数原型的定义及函数体实现中, 函数名前面都加上extern "C",然后重新编译试试.
作者: Kevin_zqw    时间: 2008-06-25 17:25
请教:
extern "C" 的具体含义是什么?
作者: zszyj    时间: 2008-06-25 18:20
原帖由 Kevin_zqw 于 2008-6-25 17:25 发表
请教:
extern "C" 的具体含义是什么?

表示这是一个C风格的函数原型, 生成目标码的内部函数符号时,不要再添加任何前缀或者后缀, 否则不同的编译器可能有不同的生成规则, 互相之间就不通用了.
作者: lipingtababa    时间: 2008-06-26 09:47
请教,在c++重载的时候,编译器也要加前缀或者后缀,请问添加规则是编译器决定的还是c++规定了的?

如果是编译器决定的,那岂不是不同编译器变异出来的库不能互相调用了?
作者: zszyj    时间: 2008-06-26 12:21
原帖由 lipingtababa 于 2008-6-26 09:47 发表
请教,在c++重载的时候,编译器也要加前缀或者后缀,请问添加规则是编译器决定的还是c++规定了的?

如果是编译器决定的,那岂不是不同编译器变异出来的库不能互相调用了?

确实存在两种编译器编译出来的库不能互相调用的情况. 我们甚至遇到过, 同一个编译器不同版本编译出来的C++库, 不能互相调用的情况, 以我的判断, 这必须不是C++的规则,而是编译器的规则, 我认为这就是为何每个C++编译器都要带一套自已的完整的库函数的原因,比如G++和VACPP及aCC都这样. C的库, 只要加上extern "C"的说明,就不存在此情况.




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2