免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3216 | 回复: 9
打印 上一主题 下一主题

[C++] linux下动态库 什么时候会链接错误(附简单例子)[ [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-08-02 19:54 |只看该作者 |倒序浏览
动态库隐式加载:
对应的so动态库文件如果有变更的话,可能整个程序需要重新编译过才能正常运行,而后者不需要。

我想知道什么情况会发生呢?实验如下:
步骤1:编译动态库和可执行函数
libmyapp.h
void myp1();

libmyapp.c
void myp1()
{
  printf("world\n");
}
gcc libmyapp.c -fPIC -shared -o libmyapp.so编译后得到libmyapp.so

调用cpp:run.cpp

#include<stdio.h>
#include"libmyapp.h"
int main()
{
  myp();
  return 0;

}

gcc -rdynamic -ldl -lmyapp -L ./ run.c -o run
得到的run正常运行。

步骤2:修改动态库
libmyapp.h
void myp1();

libmyapp.c
void myp0()
{
  printf("world0000\n");
}
void myp1()
{
  printf("world\n");
}

void myp2()
{
  printf("world2222\n");
}

gcc libmyapp.c -fPIC -shared -o libmyapp.so编译后得到libmyapp.so
本以为直接执行run会发生错误,因为动态库的增加了2个函数,切在原函数前增加了一个,也就是符号表应该变了,但是
直接执行run,程序仍能正常运行。


我测试的可能有问题,如果不会出现这种问题,就不会有COM技术的出现了,但是我的问题在哪里呢?我现在就写个中间处理程序,使动态库发生变化后,不必重新编译应用程序。

论坛徽章:
0
2 [报告]
发表于 2012-08-03 08:43 |只看该作者
别沉了别沉了

论坛徽章:
4
天秤座
日期:2013-10-18 13:58:33金牛座
日期:2013-11-28 16:17:01辰龙
日期:2014-01-14 09:54:32戌狗
日期:2014-01-24 09:23:27
3 [报告]
发表于 2012-08-03 09:34 |只看该作者
动态链接,强调的是“链接”,链接只关注符号表和对地址的重定位,跟函数指针表没有什么直接关系。试想一下静态链接的操作,就可以知道动态链接的情境了。你在静态库里面多添加一个函数,链接程序会出问题么。

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
4 [报告]
发表于 2012-08-03 09:40 |只看该作者
ben123one 发表于 2012-08-02 19:54
我测试的可能有问题,如果不会出现这种问题,就不会有COM技术的出现了,


GCC 也用这个?

论坛徽章:
0
5 [报告]
发表于 2012-08-03 10:16 |只看该作者
我是动态库so,用的是隐式连接,就是加载头文件,并且-l指定 so文件,我现在多增加一个函数,不重新编译应用程序,是没问题的。


liuiang 发表于 2012-08-03 09:34
动态链接,强调的是“链接”,链接只关注符号表和对地址的重定位,跟函数指针表没有什么直接关系。试想一下 ...

论坛徽章:
2
CU大牛徽章
日期:2013-04-17 11:46:28CU大牛徽章
日期:2013-04-17 11:46:39
6 [报告]
发表于 2012-08-03 10:17 |只看该作者
需要时,发现不成功就会报错误!

论坛徽章:
0
7 [报告]
发表于 2012-08-03 10:22 |只看该作者
能具体的说说嘛,我现在如果只导出C形式的 接口,在其前后增加都没问题。
然后导出类,如果只改接口,也没问题,然后增加了几个成员变量,也没有问题,但是一旦在构造函数显示的给成员变量赋值,就会报错



cdtits 发表于 2012-08-03 10:17
需要时,发现不成功就会报错误!

论坛徽章:
4
天秤座
日期:2013-10-18 13:58:33金牛座
日期:2013-11-28 16:17:01辰龙
日期:2014-01-14 09:54:32戌狗
日期:2014-01-24 09:23:27
8 [报告]
发表于 2012-08-03 11:42 |只看该作者
"构造函数显示的给成员变量赋值"

你是不是改构造函数原型了?

论坛徽章:
0
9 [报告]
发表于 2012-08-03 13:59 |只看该作者
当然没有啦,就是没有形参的构造函数。

我在类里面加了一个成员变量,然后在构造函数显示的赋值,就像
AA::AA()
{
  a=0;
}
或者
AA::AA()
:a(0)
{
}

都会出问题,当然,之前应用程序编译前是没有a这个成员变量的,但是加上后,也没事,只是像上面这样在构造函数弄,就出问题了


回复 8# liuiang


   

论坛徽章:
0
10 [报告]
发表于 2012-08-09 09:51 |只看该作者
应该是这样的:
1.对于纯C形式的API,你增加一个函数,不管顺序如何,都是不用重新编译源程序的;对于导出的类,增加一个类或者成员函数,不管顺序如何,也不需要重新编译源程序。因为它是以函数名查找的。
2.对于导出的虚函数,若增加一个函数,必须放在最下面,因为虚函数是以虚表的序号来的,如果放在上面,则打乱了原虚表的顺序。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP