3

I have 2 static libraries from «vendor1» and «vendor2»:

  • vendor1.lib and vendor1.h;
  • vendor2.lib and vendor2.h.

In the file, vendor1.h. The following declaration is there:

double Min();

In the file, vendor2.h. The following declaration is there:

double Min();

In my client file:

include "vendor1.h"  
include "vendor2.h"  
double x = Min();

It by defaults calls vendor1.h. I tried introducing the namespace:

   namespace vendor1 {  
    include "vendor1.h"
   }

   namespace vendor2 {  
    include "vendor2.h"
   }

A call to the following function

double xx = vendor2::Min();

I get the following linker errors:

Client.cpp 1>Client.obj : error LNK2019: unresolved external symbol "double __cdecl vendor2::Min(void)" (?Min@vendor2@@YANXZ) referenced in function _wmain 1>c:\temp\Client\Debug\Client.exe : fatal error LNK1120: 1 unresolved externals

How can I fix this without creating wrappers for each of the wrappers?

Sania Programmer
  • 264
  • 4
  • 13
  • Ugly, but you could [patch the symbol names](http://stackoverflow.com/questions/6940384/how-to-deal-with-symbol-collisions-between-statically-linked-libraries/6940389#6940389). – Georg Fritzsche Feb 07 '12 at 20:25
  • 1
    C linkage doesn't support name spaces. You can't really solve this if you want to link the two libraries statically. You could try and load them dynamically if that's an option. – Kerrek SB Feb 07 '12 at 20:28
  • Thank you. This exercise / answers cleared concepts related to namespaces and name mangling. – Sania Programmer Feb 08 '12 at 06:38

2 Answers2

2

If you have two static libraries with conflicting names you won't be able to link your program statically! The static linker will just go and find the first symbol matching an undefined symbol and choose this. Wrapping the names into a namespace doesn't help: this changes the namespace being expected in the library. You just found why namespace are a good thing.

How to solve the problem? I'm not aware of an approach which is based on the C++ standard. Practically, you may be able to do something: create a dynamic library which forwards to your conflicting functions but puts the name into separate namespaces (or uses different names). The dynamic libraries are linked with individual static libraries, i.e. the conflict doesn't happen at this time. You will probably also need to avoid the underlying names being visible from the symbols in the shared library. The details on how this is done depend on the compiler and I don't know who to deal with MSVC++ for things like this.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
1

How about wrapping the functions into different namespaces?

vendor1_wrapper.h:

namespace vendor1 {
    double Min();
}

vendor1_wrapper.cpp:

#include "vendor1_wrapper.h"
#include "vendor1.h"

namespace vendor1 {
    double Min()
    {
        return Min();
    }
}

vendor2_wrapper.h:

namespace vendor2 {
    double Min();
}

vendor2_wrapper.cpp:

#include "vendor2_wrapper.h"
#include "vendor2.h"

namespace vendor2 {
    double Min()
    {
        return Min();
    }
}

Now you can use the functions using namespaces (your client file):

#include "vendor1_wrapper.h"
#include "vendor2_wrapper.h"

...

vendor1::Min();
vendor2::Min();