Linking : Static vs Dynamic
In my application I have 3 major parts:
- Exe : an executable file
- Lib_A : a library contains a singleton class and a base class for some calculations to be use in singleton class
- Lib_B : a library contains a number of classes derived from the base in Lib_A
The reason that I have the derived classes in Lib_B is, I would like to compile the Lib_B at runtime from Exe. I need to generate derived classes during the calculations without terminating the whole system. This is too important for me. That means initially I may have say Lib_B1 dynamically loaded, also I may compile other versions of Lib_B as Lib_B2, Lib_B3, Lib_B4 etc. and load them dynamically too. All Lib_Bx libraries will have entry point functions to export the classes in them.
So taking the following facts into account :
- At runtime there will be various number of files sharing the same Lib_A.
- The application must run in Windows and Linux. So partial cross-platformness is an issue.
- I am going to use some libraries like TBB, Boost, Qt which may have their own libraries like tbb.dll etc.
What are the pros and cons of statically or dynamically linking of Lib_A against both Exe and Lib_Bx's? How can perfomance, size of system etc. be affected? Are there any dangerous or difficult situations I may encouter besides for each OS I need to use the same compiler for Exe, Lib_A and Lib_Bx's.
The desi开发者_如何转开发gn of the whole system is a very hard problem for me, so any comments will be appreciated.
Thanks very much.
From what I understand of your project description, you should link Lib_A dynamically : if you link Lib_A statically to each of your Lib_Bx shared libraries, you will duplicate x times the Lib_A code and static variables.
Say, if you have a class in Lib_A, that have the form :
class BaseKlass
{
static int instance_count;
...
};
instance_count
will be duplicated in all your shared libraries, thus make it impossible for BaseKlass
to count its instances.
You could possibly be bitten by more subtle problems with virtual tables, or RTTI (dynamic_cast), etc.
You should have a look at this boost.python document that describes problems related to what I mentionned.
Boost.python allows to create python modules (dynamic libraries) that are to be loaded in the same process. Each python module created with boost.python, if they are to communicate together at the c++ level such as deriving a class B in a module from a class A in another module, is supposed to link dynamically with boost.python lib to avoid problems.
The big advantage of static linking is that you don't have to ship a bunch of DLL's. Unless you are planing on shipping a naked executable, I think it is a non issue.
Dynamic linking has some big advantages. You don't have to recompile the entire application each time you make a change, only the modified DLLs. You can distribute updated dll's separately from the rest of the application, as long as they are ABI compatible.
It might be simpler to use the same compiler on Windows and Linux, but you definitely do not have to use the same compiler.
As long as you stick to portable libraries, the biggest difference between Windows and Linux is usually the build system. Some developers maintain completely separate build systems, but there are plenty of cross platform build system like cmake.
You want to create new classes runtime? C++ is not meant to work like that. C++ classes are static and should all exist compile time. Shared, dynamically loadable libraries are not meant to solve the issue.
Simplest solution might be to embed an interpreter of a language that has dynamic types (like Lua for example) and write the run-time dynamic objects in it.
If you really want to interact with run-time compiled modules in platform independent way then you better use some language neutral and platform neutral interface like CORBA. Then the things compiled and ran on your Linux box and Windows box can all interact with each other and compile new members to join the gang.
In principle this is all possible if all three are DLLs - you can trigger the compiler from your app and then dynamically load the new DLL. This is really just like any other plugin architecture (consider the Lib_Bx DLLs to be plugins).
I would question whether this is a wise approach though. Do you need the full flexibility of a C++ compiler for your solution? Have you profiled different ways of solving the problem? If you are doing numerical processing would something like OpenCL be a better approach?
精彩评论