在将可执行文件与静态库链接时,--whole-archive 的使用是合法的。一个示例是构建 C++ 代码,其中全局实例在其构造函数中“注册”自己(警告:未经测试的代码):
handlers.h
typedef void (*handler)(const char *data);
void register_handler(const char *protocol, handler h);
handler get_handler(const char *protocol);
handlers.cc(libhandlers.a 的一部分)
typedef map<const char*, handler> HandlerMap;
HandlerMap m;
void register_handler(const char *protocol, handler h) {
m[protocol] = h;
}
handler get_handler(const char *protocol) {
HandlerMap::iterator it = m.find(protocol);
if (it == m.end()) return nullptr;
return it->second;
}
http.cc(libhttp.a 的一部分)
#include <handlers.h>
class HttpHandler {
HttpHandler() { register_handler("http", &handle_http); }
static void handle_http(const char *) { /* whatever */ }
};
HttpHandler h; // registers itself with main!
main.cc
#include <handlers.h>
int main(int argc, char *argv[])
{
for (int i = 1; i < argc-1; i+= 2) {
handler h = get_handler(argv[i]);
if (h != nullptr) h(argv[i+1]);
}
}
请注意,http.cc 中没有 main.cc 需要的符号。如果您将其链接为
g++ main.cc -lhttp -lhandlers
您将不会获得链接到主可执行文件的 http 处理程序,并且将无法调用 handle_http()。将此与链接为时发生的情况进行对比:
g++ main.cc -Wl,--whole-archive -lhttp -Wl,--no-whole-archive -lhandlers
在纯 C 中也可以使用相同的“自我注册”样式,例如带有__attribute__((constructor)) GNU 扩展。