Distributing Windows C++ library: how to decide whether to create static or dynamic library?

情到浓时终转凉″ 提交于 2019-12-12 07:24:56

问题


We have been converting our Java and .NET API library to C++, and are trying to figure out what is the best way to distribute a compiled version to other developers to use with their custom applications. Should it be a static library or dynamic library?

We need to create for both Win32 and Win64 (and I suppose both a Debug and Release version of each target OS). Given all the frustration I've encountered trying to make sure all referenced libraries are matched (/MT versus /MD), I'm wondering if there is a decision to make here which will simplify it for other developers.

When I run dumpbin /all <static library file name> | find /i "msvc on a static library, I don't see any runtime reference (unlike when I do the same on a .exe or .dll). Does that indicate that the runtime isn't linked yet, and that gives developer more flexibility to make the /MT or /MD when they develop and build their own app?

Which approach would make the developers' life easier?


回答1:


Static libraries are easier to create but much harder to distribute. The client programmer is going to link them into his program so it is very important that your compile settings are compatible with his. You must distribute at least 4 versions, corresponding with the 4 different CRT versions (/MD, /MDd, /MT, /MTd). And you need to multiply this by the number of Visual Studio versions that are in common use. If you don't know what the client programmer is going to use then that's potentially a very large list.

Not a problem with a DLL, you only supply a single .h for the exported function declarations, a .lib that's the import library for the DLL (no code, just contains names) and the .dll itself.

It is however harder to create an interface for your DLL that's usable from any C or C++ compiler. You cannot expose any standard C++ library classes, returning an std::string is not going to work for example. You cannot create any function that allocates memory that needs to be released by the caller. You cannot in general throw exceptions across the boundary. Doing any of these things tend to cause very hard to diagnose runtime problems for the client programmer, caused by mismatched memory allocators and class object layout differences. The COM object model is an example of such an interface.

This is not the kind of problem you'd have with static libraries. Somewhat by accident, they require a runtime and compiler version match. If the client programmer is stuck with a static library that's the wrong flavor then he'll have all of those problems as well. And more. Static libraries are like teenage sex. You make one mistake and end up supporting it for the rest of your life.




回答2:


There are significant advantages to both static and dynamic (shared) libraries. Maybe one option for you is to distribute both types of libraries, and let the library users decide which to use.

For myself, I usually use static libraries unless I think the advantages of a dynamic library are meaningful for the project.

Among the advantages of a static library:

  • Once linked in at compile-time by the user of the library, the code in the library is always in the same module that needs to call it. So no DLL hell, and no side-by-side hell. I cannot count the number of times I've tried to run a program on Windows only for it to fail because I don't have the right version of the MSVC runtime (DLL) installed. This is really a pain and if it can be avoided, it makes everyone's life easier.
  • Similarly, the symbols for the code in the library will end up in the .pdb of the module that calls the library, rather than in another .pdb (the .pdb of the .dll) that you have to keep track of, copy around, etc.
  • This is minor, but for static libraries only the functions/data you need to link it end up in the executable. Whereas for a DLL, it's the whole enchilada.

Among the advantages of a dynamic library

  • The obvious advantage is that it allows the library to be replaced at runtime, even by an end-user, without a relink.
  • This is minor in most environments, but if a lot of executables link the library in, having a DLL means less disk space since the same data/code isn't repeated in every executable.
  • Something that isn't always appreciated: if the library is going to be loaded by multiple processes at the same time, providing it as a DLL means - ideally - only one copy of the read-only data (and even the writable data until and unless it is written to by a particular process) needs to be in memory. All the processes that runtime-link the DLL share the same bytes in memory. The memory shared is both total virtual memory (RAM+pagefile) and physical memory. However this is all only best-case - if the DLL can't be loaded at the same virtual address in two processes, they can't share it.


来源:https://stackoverflow.com/questions/18024034/distributing-windows-c-library-how-to-decide-whether-to-create-static-or-dyna

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!