When to use dynamic vs. static libraries

2019-01-01 16:24发布

When creating a class library in C++, you can choose between dynamic (.dll, .so) and static (.lib, .a) libraries. What is the difference between them and when is it appropriate to use which?

18条回答
步步皆殇っ
2楼-- · 2019-01-01 16:48

If your library is going to be shared among several executables, it often makes sense to make it dynamic to reduce the size of the executables. Otherwise, definitely make it static.

There are several disadvantages of using a dll. There is additional overhead for loading and unloading it. There is also an additional dependency. If you change the dll to make it incompatible with your executalbes, they will stop working. On the other hand, if you change a static library, your compiled executables using the old version will not be affected.

查看更多
宁负流年不负卿
3楼-- · 2019-01-01 16:48

If the library is static, then at link time the code is linked in with your executable. This makes your executable larger (than if you went the dynamic route).

If the library is dynamic then at link time references to the required methods are built in to your executable. This means that you have to ship your executable and the dynamic library. You also ought to consider whether shared access to the code in the library is safe, preferred load address among other stuff.

If you can live with the static library, go with the static library.

查看更多
临风纵饮
4楼-- · 2019-01-01 16:52

Creating a static library

$$:~/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]>

creating a dynamic library

$$:~/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]>
查看更多
残风、尘缘若梦
5楼-- · 2019-01-01 16:53

We use a lot of DLL's (> 100) in our project. These DLL's have dependencies on each other and therefore we chose the setup of dynamic linking. However it has the following disadvantages:

  • slow startup (> 10 seconds)
  • DLL's had to be versioned, since windows loads modules on uniqueness of names. Own written components would otherwise get the wrong version of the DLL (i.e. the one already loaded instead of its own distributed set)
  • optimizer can only optimize within DLL boundaries. For example the optimizer tries to place frequently used data and code next to each other, but this will not work across DLL boundaries

Maybe a better setup was to make everything a static library (and therefore you just have one executable). This works only if no code duplication takes place. A test seems to support this assumption, but i couldn't find an official MSDN quote. So for example make 1 exe with:

  • exe uses shared_lib1, shared_lib2
  • shared_lib1 use shared_lib2
  • shared_lib2

The code and variables of shared_lib2 should be present in the final merged executable only once. Can anyone support this question?

查看更多
听够珍惜
6楼-- · 2019-01-01 16:54

I'd give a general rule of thumb that if you have a large codebase, all built on top of lower level libraries (eg a Utils or Gui framework), which you want to partition into more manageable libraries then make them static libraries. Dynamic libraries don't really buy you anything and there are fewer surprises -- there will only be one instance of singletons for instance.

If you have a library that is entirely separate to the rest of the codebase (eg a third party library) then consider making it a dll. If the library is LGPL you may need to use a dll anyway due to the licensing conditions.

查看更多
明月照影归
7楼-- · 2019-01-01 16:56

Ulrich Drepper's paper on "How to Write Shared Libraries" is also good resource that details how best to take advantage of shared libraries, or what he refers to as "Dynamic Shared Objects" (DSOs). It focuses more on shared libraries in the ELF binary format, but some discussions are suitable for Windows DLLs as well.

查看更多
登录 后发表回答