简体   繁体   中英

In C/C++, how do I determine if a library is statically linked or not

I have a static library that provides some functionality. I have applications that use this library. Some of these applications are command line applications or run as daemons/services. Some of these applications are GUI applications.

The library offers functionality to provide GUI elements to allow it to be configured by the user. I build the library in two flavours; a GUI flavour and a CLI flavour. I then link the appropriate version to the application.

I would like to be able to improve/simplify matters by separating the GUI functionality of this library into a separate "extension" library that provides GUI support. My plan is that at runtime the main library somehow detects the presence of the GUI support library. If present then it instantiates an object from the GUI library that provides the necessary functionality, and if not it instantiates an object from itself that provides the same APIs as "stub" functions that do nothing or return errors as appropriate. The two objects would inherit from a common pure virtual abstract base class.

This must be done at runtime because I want to be able to link exactly the same binary of the main library to both CLI and GUI applications, and not rely on compile time switches which, by definition, result in differing binaries.

I have been thinking along the lines of implementing a function in the main library like this:

bool SupportsGUI() { return false; }

and then implementing the same function in the GUI support library like this:

bool SupportsGUI() { return true; }

and then, when linking the application, somehow force the linker to resolve the link to use the one from the GUI support library if present.

I cannot figure out how to get this to work.

Assuming that both libraries are static libraries how can I, at runtime, determine from one library whether the linking application has also linked the other?

Alternatively, how can I, at link time, override a set of functions implemented in one library with an equivalent set of functions implemented in a separate library.

This does not need to be done as runtime. The common solution is to use a weak symbol . This is a symbol in a library that's used when there is no "normal" symbol to link against. Your base library provides the weak symbols, your GUI library optionally provides replacements, and the static linker figures it out.

You need a plugin loading system for this.

  1. Plugin API library defines the interface (eg an abstract class defining some virtual functions you want to be able to call)

  2. Plugin implements the actual GUI code. This is then a shared library that is loaded at runtime, with a hardcoded path and some form of configurable or fixed path/filename. Other plugin, or application itself implements fallback implementation that is used if hardcoded plugin.

  3. The application then tries to load the GUI plugin and calls a specific function from that dynamically loaded library to create the GUI specific plugin object. If the plugin cannot be loaded, it instantiates the fallback object.

There are many helper libraries you can use to do this kind of thing. Qt has a QPluginLoader class but there are various other semi-generic wrappers to load dynamic libraries and instantiate plugin interfaces from them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM