What if two libraries provide a function with the same name as the conflict?

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

+61
c conflict name-collision
Mar 24 '09 at 16:47
source share
12 answers
  • If you control one or both: edit it to change the name and recompile. Or similarly, see Ben and unknown answers that will work without access to the source code.
  • If you do not control any of them, you can wrap one of them. This compiles another ( statically linked !) Library that does nothing but re-export all the characters of the original, except for the offensive, which is achieved through a shell with an alternative name. What a hassle.
  • Added later:. As qeek says he talks about dynamic libraries, the solutions offered by Ferruccio and mouviciel are probably the best. (It seems that I live in the old days, when static binding was the default. It colors my thoughts.)

Regarding the comments: β€œExport” I want to make visible for the modules associated with the library - equivalent to the extern keyword in the file area. How this is controlled depends on the OS and linker. And this is what I always need to look for.

+35
Mar 24 '09 at 17:02
source share

You can rename characters in an object file using objcopy --redefine-sym old=new file (see man objcopy).

Then just call the functions using their new names and linking to the new object file.

+34
Mar 24 '09 at 17:20
source share

On Windows, you can use LoadLibrary () to load one of these libraries into memory, and then use GetProcAddress () to get the address of each function that you need to call and call the functions using the function pointer.

eg.

 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); 

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

I know that Unix systems support similar functionality, but I can't come up with their names.

+10
Mar 24 '09 at 17:38
source share

Here is a thought. Open one of the intruder libraries in a hex editor and change all occurrences of the intruder strings to something else. Then you can use the new names in all future calls.

UPDATE: I just did it for this purpose and it seemed to work. Of course, I did not test it completely - it can be nothing more than a really good way to blow a leg with a gun with hexedite.

+8
March 24. '09 at 17:12
source share

You should not use them together. If I remember correctly, the linker throws an error in this case.

I have not tried, but the solution could be with dlopen() , dlsym() and dlclose() , which allow you to program dynamic libraries programmatically. If you do not need two functions at the same time, you can open the first library, use the first function and close the first library before using the second library / function.

+5
Mar 24 '09 at 17:01
source share

Swear it? As far as I know, you cannot do this if you have two libraries that expose reference points with the same name, and you need to link them to both.

+4
Mar 24 '09 at 16:54
source share

This problem is the reason that C ++ has namespaces. There is no really great solution in c for 2 third-party libraries having the same name.

If it is a dynamic object, you can explicitly load the shared objects (LoadLibrary / dlopen / etc) and call it that way. Alternatively, if you do not need both libraries simultaneously in the same code, you can do something with a static link (if you have .lib / .a files).

None of these solutions apply to all projects, of course.

+4
Mar 24 '09 at 17:02
source share

Assuming you are using Linux, you first need to add

 #include <dlfcn.h> 

Declare a function pointer variable in the appropriate context, e.g.

 int (*alternative_server_init)(int, char **, char **); 

As Ferruccio stated in https://stackoverflow.com/a/3/93514/ ... , explicitly load the library that you want to use by executing (select your favorite flags)

 void* dlhandle; void* sym; dlhandle = dlopen("/home/jdoe/src/libwhatnot.so.10", RTLD_NOW|RTLD_LOCAL); 

Read the address of the function you want to call later

 sym = dlsym(dlhandle, "conflicting_server_init"); 

assign and produce as follows

 alternative_server_init = (int (*)(int, char**, char**))sym; 

Call like the original. Finally, unload by doing

 dlclose(dlhandle); 
+4
Jul 04 '13 at 14:12
source share

You should write a wrapper library around one of them. Your wrapper library should expose characters with unique names and not expose characters with unique names.

Another option is to rename the function name in the header file and rename the symbol in the archive of library objects.

In any case, to use both options, it will be hard work.

+2
Mar 24 '09 at 17:07
source share

I have never used dlsym, dlopen, dlerror, dlclose, dlvsym etc., but I look at the man page and this gives an example of opening libm.so and extracting the cos function. Does dlopen run a collision search process? If this is not the case, the OP can simply load both libraries manually and assign new names to all the functions that its libraries provide.

0
March 24. '09 at 17:06
source share

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

Summary:

  • objcopy --prefix-symbols=pre_string test.o to rename characters in a .o file

or

  1. objcopy --redefine-sym old_str=new_str test.o to rename a specific character in the .o file.
0
Dec 29 '16 at 8:19
source share

The question is approaching a ten-year one, but there are new searches all the time ...

As already mentioned, objcopy with the -redefine-sym flag is a good choice on Linux. See, for example, https://linux.die.net/man/1/objcopy for full documentation. This is a little clumsy because you essentially copy the entire library when you make changes, and for each update you need to repeat this work. But at least it should work.

For Windows, dynamic loading of the library is a solution, and there will be a permanent one, such as the dlopen alternative on Linux. However, both dlopen () and LoadLibrary () add additional code that can be avoided if the only problem is duplicate names. Here, the Windows solution is more elegant than the objcopy approach: just tell the linker that the characters in the library are known by a different name and use that name. Here are a few steps to do this. You need to create a def file and provide a name translation in the EXPORTS section. See https://msdn.microsoft.com/en-us/library/hyx1zcd3.aspx (VS2015, it will eventually be replaced with newer versions) or http://www.digitalmars.com/ctg/ctgDefFiles.html (possibly more persistent) to get complete syntax information for the def file. This process was to make a def file for one of the libraries, then use this def file to create the lib file, and then link it to this lib file. (For Windows DLLs, lib files are used only for linking, not code execution.) See How to make a .lib file when there is a .dll file and a header file for the process of creating the lib file. Here the only difference is the addition of aliases.

For Linux and Windows, rename functions in the library headers whose names are aliases. Another option that should work is in the files related to the new names, in #define old_name new_name, #include the headers of the library whose export is smoothed, and then the name #undef old_name in the caller. If there are a lot of files in the library, it is easier to use a heading or headings that wrap definitions, include and cancel, and then use that heading.

Hope this information has been helpful!

0
Nov 01 '17 at 19:59 on
source share



All Articles