What should I do if two libraries provide a function with the same name generating a conflict?

56,359

Solution 1

  • If you control one or both: edit one to change the name and recompile Or equivalently see Ben and unknown's answers which will work without access to the source code.
  • If you don't control either of them you can wrap one of them up. That is compile another (statically linked!) library that does nothing except re-export all the symbols of the original except the offending one, which is reached through a wrapper with an alternate name. What a hassle.
  • Added later: Since qeek says he's talking about dynamic libraries, the solutions suggested by Ferruccio and mouviciel are probably best. (I seem to live in long ago days when static linkage was the default. It colors my thinking.)

Apropos the comments: By "export" I mean to make visible to modules linking to the library---equivalent to the extern keyword at file scope. How this is controlled is OS and linker dependent. And it is something I always have to look up.

Solution 2

It is possible to rename symbols in an object file using objcopy --redefine-sym old=new file (see man objcopy).

Then just call the functions using their new names and link with the new object file.

Solution 3

Under Windows, you could use LoadLibrary() to load one of those libraries into memory and then use GetProcAddress() to get the address of each function you need to call and call the functions through a function pointer.

e.g.

HMODULE lib = LoadLibrary("foo.dll");
void *p = GetProcAddress(lib, "bar");
// cast p to the approriate function pointer type (fp) and call it
(*fp)(arg1, arg2...);
FreeLibrary(lib);

would get the address of a function named bar in foo.dll and call it.

I know Unix systems support similar functionality, but I can't think of their names.

Solution 4

If you have .o files there, a good answer here: https://stackoverflow.com/a/6940389/4705766

Summary:

  1. objcopy --prefix-symbols=pre_string test.o to rename the symbols in .o file

or

  1. objcopy --redefine-sym old_str=new_str test.o to rename the specific symbol in .o file.

Solution 5

Here's a thought. Open one of the offending libraries in a hex editor and change all occurrences of the offending strings to something else. You should then be able to use the new names in all future calls.

UPDATE: I just did it on this end and it seems to work. Of course, I've not tested this thoroughly - it may be no more than a really good way to blow your leg off with a hexedit shotgun.

Share:
56,359

Related videos on Youtube

qeek
Author by

qeek

I build cool things

Updated on July 08, 2022

Comments

  • qeek
    qeek about 2 years

    What should I do if I have two libraries that provide functions with equivalent names?

    • Alnitak
      Alnitak over 15 years
      are these static libraries or dynamically linked?
    • Johannes Schaub - litb
      Johannes Schaub - litb over 15 years
      we need more details... are those names exported? or are they used internally only? Can you change the names?
    • Vortico
      Vortico over 10 years
      Great question. Of course it wouldn't be a problem with these two libraries if all the symbols were prefixed with a unique ID (e.g. vorbis_..., sf_..., sdl_...). This is essentially what C++ does to the symbol names for namespaced functions.
    • yugr
      yugr about 5 years
      This is a very interesting question but is sadly too imprecise which is the reason for having too many too broad answers.
  • dmckee --- ex-moderator kitten
    dmckee --- ex-moderator kitten over 15 years
    Swear is definitely the first step. No doubt about it.
  • qeek
    qeek over 15 years
    Thanks. Didn't think about this. Although, I'd like to have both at the same time.
  • Sniggerfardimungus
    Sniggerfardimungus over 15 years
    That was my first thought as well, but won't you end up with the same collision problem? In the end, the entire project has to link - at compile/link time or at run time - at which time both the offending libraries have to load as-is.
  • dmckee --- ex-moderator kitten
    dmckee --- ex-moderator kitten over 15 years
    @unknown: The wrapper must be compiled with static linkage, and should not export the offending symbol. Then you can still dynamically link the wrapper. Edited for more clarity, Thanks.
  • jeffD
    jeffD over 15 years
    If qeek's problem is with ddl's and not static libraries, how is it possible to make a new library with a wrapper? Since, the wrapper library would have to dynamically wrap around a function in the library you don't want to link with in the first place.
  • Admin
    Admin over 15 years
    @dmckee - what do you mean by "export"?
  • dmckee --- ex-moderator kitten
    dmckee --- ex-moderator kitten over 15 years
    @Neil: Expose. Make visible to modules linking to the library. Equivalent to extern and file level in c.
  • Jason
    Jason over 15 years
    actually not a terrible solution. A bit hackish, but all you'd be doing is changing the strings in the symbol table. No real functional harm in that.
  • dmckee --- ex-moderator kitten
    dmckee --- ex-moderator kitten over 15 years
    @Neil: It is a function of the linker. You can generally tell your linker to construct library C out of code A and library B without exposing the symbols from B. Or exposing only selected symbols. How to specify it is system dependent.
  • Admin
    Admin over 15 years
    perhaps someone could provide a simple example of this technique? One exe, two libraries each containing one function with the same name.
  • Sniggerfardimungus
    Sniggerfardimungus over 15 years
    You'd probably want to rename the library, as well - lest someone else came along, trying to load the thing again. You'd go from one conflict to dozens or hundreds. =] I love this about stackoverflow: we have a tested answer to a question and it has 3 votes. The first (incomplete) answer: 17. =]
  • mouviciel
    mouviciel over 15 years
    Don't forget to rename the symbols in the header files as well.
  • Tomasz Gandor
    Tomasz Gandor almost 10 years
    Oh yes. For this general question this seems like a good answer. However - namespaces are cool if you compile everything together in the same compiler. Hooray, no name clashes. But if you get a library in binary form, and want to integrate it with another compiler, then - good luck. Name mangling rules in object files are just the first obstackle (extern "C" may help, which undoes the namespaces' efect).
  • QZHua
    QZHua about 8 years
    What if I'd like to use both at the same time?
  • mouviciel
    mouviciel about 8 years
    @QZHua: Other anwsers (e.g., involving symbol renaming) should solve your problem.
  • user877329
    user877329 almost 8 years
    dlopen dlsym, and dlclose. However, the encapsulation on Unix may not be as effective as on Windows.
  • Alex Reinking
    Alex Reinking over 5 years
    ^ sed/awk/perl would be useful to automate renaming the symbols in the header, too
  • yugr
    yugr about 5 years
  • yugr
    yugr about 5 years
  • yugr
    yugr about 5 years
    Renaming opportunities are limited as you'll only be able to make names shorter. Also on Linux you'll have hard time updating ELF hash tables.
  • yugr
    yugr about 5 years
  • yugr
    yugr about 5 years
    "there isn't much you can do" - is this still relevant? Other answers provide numerous different solutions.