On Linux, it will be easier for you to link to the shared library and use symbolic links to fix the version - IMO is much easier than using dlopen() + dlsym() .
This way you will create shared libraries for the old and new versions of your library:
g++ -shared -o libshared.so.1.1 -Wl,-soname=libshared.so.1 -L. -Wl,--whole-archive libstatic.a.old -Wl,-no-whole-archive
and
g++ -shared -o libshared.so.1.2 -Wl,-soname=libshared.so.1 -L. -Wl,--whole-archive libstatic.a.new -Wl,-no-whole-archive
Create symbolic links:
ln -s libshared.so.1.1 libshared.so.1 ln -s libshared.so.1 libshared.so
Create an application by linking it to an old version of the library. I believe that both versions are binary compatible (ABI is not broken), but the new one may have several new characters.
g++ -o myapp myapp.cpp -L. -lshared
Since the SONAME shared library is libshared.so.1 , your application will depend on it and will look for libshared.so.1 in the paths from /etc/ld.so.conf or LD_LIBRARY_PATH
Before starting the application, you can set the libshared.so.1 symbolic link to point to libshared.so.1.2 or libshared.so.1.1 .
Some information on the linker options used here:
- all-archive
For each archive specified on the command line after the -whole-archive option, include each object file in the archive in the link, rather than search the archive for the necessary object files. This is usually used to turn an archive file into a shared library, forcing each object to be included in the resulting shared library. This option can be used several times.
Two notes when using this option from gcc: firstly, gcc does not know about this option, so you need to use -Wl, -all archive. Secondly, do not forget to use -Wl, -no-whole-archive after the list of archives, because gcc will add its own list of archives to yours and you may not want this flag to affect them either.
-soname = name
When creating a shared ELF object, set the DT_SONAME internal field to the specified name. When the executable is associated with a shared object that has a DT_SONAME field, then when the executable is launched, the dynamic linker will try to load the shared object specified by the DT_SONAME field, rather than the file name assigned to the linker.