在c++中创建类库时,可以在动态(.dll, .so)和静态(.dll, .so)之间进行选择。Lib, .a)库。它们之间的区别是什么?什么时候使用哪个比较合适?


当前回答

真正的权衡(在一个大型项目中)是在初始加载时间,库将在某个时间被链接,必须做出的决定是链接是否需要足够长的时间,以至于编译器需要咬紧牙关并提前完成,还是动态链接器可以在加载时完成。

其他回答

您应该仔细考虑随时间的变化、版本控制、稳定性、兼容性等。

如果有两个应用程序使用共享代码,您是否希望强制这些应用程序一起更改,以防它们需要相互兼容?然后使用dll。所有的exe都将使用相同的代码。

或者你想把它们彼此隔离,这样你就可以改变一个,并确信你没有破坏另一个。然后使用静态库。

DLL地狱是当你可能应该使用一个静态库,但你使用了一个DLL代替,并不是所有的前任都与它兼容。

静态库必须链接到最终的可执行文件中;它成为可执行文件的一部分,并跟随它到任何地方。每次执行可执行文件时都会加载动态库,并以DLL文件的形式与可执行文件分开。

当您希望能够更改库提供的功能而不必重新链接可执行文件(只需替换DLL文件,而不必替换可执行文件)时,您将使用DLL。

当您没有理由使用动态库时,您可以使用静态库。

如果你在嵌入式项目或专门的平台上工作,静态库是唯一的方法,而且很多时候它们编译到你的应用程序中不是那么麻烦。同时,拥有包含一切的项目和makefile会让生活更快乐。

真正的权衡(在一个大型项目中)是在初始加载时间,库将在某个时间被链接,必须做出的决定是链接是否需要足够长的时间,以至于编译器需要咬紧牙关并提前完成,还是动态链接器可以在加载时完成。


创建静态库

$$:~/static [32]> cat foo.c
#include<stdio.h>
void foo()
{
printf("\nhello world\n");
}
$$:~/static [33]> cat foo.h
#ifndef _H_FOO_H
#define _H_FOO_H

void foo();

#endif
$$:~/static [34]> cat foo2.c
#include<stdio.h>
void foo2()
{
printf("\nworld\n");
}
$$:~/static [35]> cat foo2.h
#ifndef _H_FOO2_H
#define _H_FOO2_H

void foo2();

#endif
$$:~/static [36]> cat hello.c
#include<foo.h>
#include<foo2.h>
void main()
{
foo();
foo2();
}
$$:~/static [37]> cat makefile
hello: hello.o libtest.a
        cc -o hello hello.o -L. -ltest
hello.o: hello.c
        cc -c hello.c -I`pwd`
libtest.a:foo.o foo2.o
        ar cr libtest.a foo.o foo2.o
foo.o:foo.c
        cc -c foo.c
foo2.o:foo.c
        cc -c foo2.c
clean:
        rm -f foo.o foo2.o libtest.a hello.o

$$:~/static [38]>

创建动态库

$$:~/dynamic [44]> cat foo.c
#include<stdio.h>
void foo()
{
printf("\nhello world\n");
}
$$:~/dynamic [45]> cat foo.h
#ifndef _H_FOO_H
#define _H_FOO_H

void foo();

#endif
$$:~/dynamic [46]> cat foo2.c
#include<stdio.h>
void foo2()
{
printf("\nworld\n");
}
$$:~/dynamic [47]> cat foo2.h
#ifndef _H_FOO2_H
#define _H_FOO2_H

void foo2();

#endif
$$:~/dynamic [48]> cat hello.c
#include<foo.h>
#include<foo2.h>
void main()
{
foo();
foo2();
}
$$:~/dynamic [49]> cat makefile
hello:hello.o libtest.sl
        cc -o hello hello.o -L`pwd` -ltest
hello.o:
        cc -c -b hello.c -I`pwd`
libtest.sl:foo.o foo2.o
        cc -G -b -o libtest.sl foo.o foo2.o
foo.o:foo.c
        cc -c -b foo.c
foo2.o:foo.c
        cc -c -b foo2.c
clean:
        rm -f libtest.sl foo.o foo

2.o hello.o
$$:~/dynamic [50]>