LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1988|回复: 30

链接与库的一个问题

[复制链接]
发表于 2005-9-22 14:29:23 | 显示全部楼层 |阅读模式
一个程序的模块这样分:
有一个library族(多个.a的一个包),我针对它写一份API;然后其他人写源码时只用我的API,而不调用那个library族 的接口。
我把我写的API编译成.o文件,可是其它人用这个.o不能完成链接。
考虑到我只调用library族的数个接口而已,我想有没有办法把我写的API编译成某种东东(.o或者.a),独立于那个library,然后其它人可以用我编译的结果就能进行链接,甚至不再需要那个library族进行链接。
如果可以的话,编译时用什么参数?谢谢。
发表于 2005-9-22 14:39:12 | 显示全部楼层
你所说的API指的是?
回复 支持 反对

使用道具 举报

发表于 2005-9-22 16:21:17 | 显示全部楼层
直接把那些library和你自己写的东东,统一做成一个新连接库,动态或者静态的都行,然后就用新生成的库即可。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-9-22 23:32:07 | 显示全部楼层
Post by rickxbx
你所说的API指的是?

不好意思。就是一些函数,我写了一批函数,它们调用库里的函数;然后让别人调用我的函数;库的复杂丢给了我,我还要向其它人写例子说明我的函数怎么用……最后链接和调试也归俺 :comp
回复 支持 反对

使用道具 举报

发表于 2005-9-23 08:56:36 | 显示全部楼层
把你写的API编译成静态库应该可以,你试一下。
回复 支持 反对

使用道具 举报

发表于 2005-9-23 13:01:46 | 显示全部楼层
Post by Illidan
不好意思。就是一些函数,我写了一批函数,它们调用库里的函数;然后让别人调用我的函数;库的复杂丢给了我,我还要向其它人写例子说明我的函数怎么用……最后链接和调试也归俺 :comp


我觉得如果要在链接的时候不需要连接到那个库的话,那个库应该是共享库,因为要使编译/链接的时候不报错,只能是动态链接.
然后,要使别人调用你的API,你既可以提供静态库(.a),也可以提供动态库(.so),如果提供静态库,就需要用户使用静态链接,如果提供动态库,用户就可以使用动态连接.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-9-23 17:24:47 | 显示全部楼层
Post by kj501
把你写的API编译成静态库应该可以,你试一下。

我没有手工打包,而是利用原库文档的Makefile模板打包了一个.a, 用nm一看,像这样:
00001168 T _Z8from_setP6from_tPcP9sip_uri_tS1_
000002bc T _Z8list_addP6list_tP4nodei
0000043e T _Z8list_delP6list_ti
0000025c T _Z8list_eolP6list_ti
00000594 T _Z8list_getP6list_ti
00000046 T _Z8our_freePv
000015fe T _Z8to_printP6from_t
00000d3a T _Z8via_freeP3via
00000c86 T _Z8via_initPP3via
00001ab6 T _Z9cseq_freeP6cseq_t
00001a34 T _Z9cseq_initPP6cseq_t

加了些奇怪的前后缀,函数原来叫from_set等等。

看make的输出,也很平常:
ar rv obj.debug.Linux.i686/libsipmsg.a obj.debug.Linux.i686/sip_msg.o || rm obj.debug.Linux.i686/libsipmsg.a
a - obj.debug.Linux.i686/sip_msg.o
ranlib obj.debug.Linux.i686/libsipmsg.a || rm obj.debug.Linux.i686/libsipmsg.a

用这个libsipmsg去做静链,失败了,报告undefined reference。
回复 支持 反对

使用道具 举报

发表于 2005-9-23 17:28:40 | 显示全部楼层
把那些函数加上 extern "C" 前缀。
回复 支持 反对

使用道具 举报

发表于 2005-9-23 21:42:38 | 显示全部楼层
Post by herberteuler
把那些函数加上 extern "C" 前缀。

在头文件里
像这样
#ifdef __cplusplus
extern "C" {
#endif

void func();

#ifdef __cplusplus
}
#endif

c++里为了实现重载,允许函数重名
但是在连接的时候函数名实际还是不一样的
就像你看到的,那是c++的symbol name mangle的结果
mangle时的依据有很多,至少有函数名,参数类型,个数,顺序

如果通过extern "C"指定c linkage
那么就不会mangle symbol name了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-9-24 11:05:11 | 显示全部楼层
Post by zhllg
在头文件里
像这样
#ifdef __cplusplus
extern "C" {
#endif

void func();

#ifdef __cplusplus
}
#endif

c++里为了实现重载,允许函数重名
但是在连接的时候函数名实际还是不一样的
就像你看到的,那是c++的symbol name mangle的结果
mangle时的依据有很多,至少有函数名,参数类型,个数,顺序

如果通过extern "C"指定c linkage
那么就不会mangle symbol name了



加了那些预处理指令,果然可以去掉奇怪的前后缀了。

不过,链接还是有"undefined reference"的错误。后来我直接用.o而不是.a,仍然"undefined reference: to `list_free'";我nm看那个.o,那个函数的名字明明有:
00001da T list_free
(它绝对定义过,我自己写的)

这可能是什么原因呢?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表