Chinaunix

标题: linux下动态库 什么时候会链接错误(附简单例子)[ [打印本页]

作者: ben123one    时间: 2012-08-02 19:54
标题: linux下动态库 什么时候会链接错误(附简单例子)[
动态库隐式加载:
对应的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技术的出现了,但是我的问题在哪里呢?我现在就写个中间处理程序,使动态库发生变化后,不必重新编译应用程序。

作者: ben123one    时间: 2012-08-03 08:43
别沉了别沉了
作者: liuiang    时间: 2012-08-03 09:34
动态链接,强调的是“链接”,链接只关注符号表和对地址的重定位,跟函数指针表没有什么直接关系。试想一下静态链接的操作,就可以知道动态链接的情境了。你在静态库里面多添加一个函数,链接程序会出问题么。
作者: MMMIX    时间: 2012-08-03 09:40
ben123one 发表于 2012-08-02 19:54
我测试的可能有问题,如果不会出现这种问题,就不会有COM技术的出现了,


GCC 也用这个?
作者: ben123one    时间: 2012-08-03 10:16
我是动态库so,用的是隐式连接,就是加载头文件,并且-l指定 so文件,我现在多增加一个函数,不重新编译应用程序,是没问题的。


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

作者: cdtits    时间: 2012-08-03 10:17
需要时,发现不成功就会报错误!
作者: ben123one    时间: 2012-08-03 10:22
能具体的说说嘛,我现在如果只导出C形式的 接口,在其前后增加都没问题。
然后导出类,如果只改接口,也没问题,然后增加了几个成员变量,也没有问题,但是一旦在构造函数显示的给成员变量赋值,就会报错



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

作者: liuiang    时间: 2012-08-03 11:42
"构造函数显示的给成员变量赋值"

你是不是改构造函数原型了?
作者: ben123one    时间: 2012-08-03 13:59
当然没有啦,就是没有形参的构造函数。

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

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


回复 8# liuiang


   
作者: ben123one    时间: 2012-08-09 09:51
应该是这样的:
1.对于纯C形式的API,你增加一个函数,不管顺序如何,都是不用重新编译源程序的;对于导出的类,增加一个类或者成员函数,不管顺序如何,也不需要重新编译源程序。因为它是以函数名查找的。
2.对于导出的虚函数,若增加一个函数,必须放在最下面,因为虚函数是以虚表的序号来的,如果放在上面,则打乱了原虚表的顺序。




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