1

Is there a way to expose a symbol only to dlsym and hide it during static and dynamic linking?

What I'd like to do is allow for object files that can be used either as shared libraries or plugins without modification. If the object files are going to be usable as libraries, symbol collisions have to be avoided. Unfortunately, this means that when used as plugins, the name of the function that dlsym will use to initialize the plugin has to be different for each plugin. CPython solves this by relating the symbol name dlsym will look for to the filename of the shared object. This is an ok solution but it breaks if the shared objects are renamed.

Instead, I'd prefer for plugins to expose a common initialization function name to dlsym but for this name to be ignored if the shared object is being dynamically linked. (In that case, initialization would be done some other way.)

Edit: I was mistaken about the premise of the question. With dynamic libs A and B that export identical symbols, if a program links to both of them it doesn't cause a linker error.

Praxeolitic
  • 22,455
  • 16
  • 75
  • 126
  • I don't think it's possible, The only solution is to create two library. http://stackoverflow.com/questions/2222162/how-to-apply-gcc-fvisibility-option-to-symbols-in-static-libraries. – Stargateur Jan 12 '17 at 12:53
  • The simplest solution would be *not to link* against your library. – tofro Jan 12 '17 at 13:26
  • @tofro Huh? The question is literally asking how I can allow these libraries to be linked against. – Praxeolitic Jan 12 '17 at 13:36
  • @Praxeolitic a dll can either be a plugin that's not being linked against during link time or it can be a(shared) library, then it needs to conform to certain requirements - no duplicate symbols, for example. You want **both** and that is not possible.What you could be doing is create a *linkable* library acting as a sort of front-end that loads the plugins. This would conform with both requirements. – tofro Jan 12 '17 at 13:53

1 Answers1

3

No, dlsym and dynamic linker share implementation so it's not possible to hide symbol from one while exposing to other.

What you could do in your particular case instead, is use the same function name (or, better, exported string literal) for all plugins. Then you could iterate over all loaded shared libraries and query for this function via dlsym(handle, common_name).

yugr
  • 19,769
  • 3
  • 51
  • 96