Conflict resolution using multiple static libraries in C++ - c++

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?

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.

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

Related

Creating class object defined in another project

I have a Visual C++ solution with 2 projects: rectangle and project3.
In rectangle project I have rect.cpp and rect.h.
rect.h
#ifndef rect_h
#define rect_h
class Rect
{
public:
Rect();
int m_h;
int m_w;
};
#endif //rect_h
rect.cpp
#include "rect.h"
Rect::Rect()
{
m_h = 1;
m_w = 5;
}
whenever I try to create rect object from the rectangle project it succeeds.
But when I try to do the same from the project3 it produces a linker error.
LNK2019: unresolved external symbol "public: __thiscall
Rect::Rect(void)" (??0Rect##QAE#XZ) referenced in function _main
1>C:\Users\mbaro\documents\visual studio
2017\Projects\Project2\Debug\Project3.exe : fatal error LNK1120: 1
unresolved externals
main.cpp (in project 3)
#include "rect.h"
using namespace std;
int main()
{
Rect* a = new Rect();
return 0;
}
I kind of feel that class definition is picked up successfully, but the linker can not link the constructor code from rect.cpp.
What is the problem and how to solve it?
Thanks.
The error is normal: you told the compiler where it could find the .h files, but you did not tell the linker where it could find the .obj files.
It may depend on the exact VS version, but in Project/Properties, you should find Linker/Input and there Additional dependencies. If you only need one or two object files (xxx.obj) from the other project, add them here. That way, you avoid code duplication, which will be a nightmare for future maintenance...
If you have many common files, you should considere to put them in an auxilliary project that would build a (static)library in the same solution, and then link the library in both project (and of course give access to header files of the library project for the other projects using the library).
I have already started writing a long, long answer. Then i realized, what You may be missing is that despite Your class is named "Person" the header file You should have added is named "rect.h".
Also Your constructor cannot have a declaration of values in the header file (EDIT:not true, I was mistaken). In the header file, try using:
Person(int h, int w);
You declare what will be needed, not what You already have. If You want those to be specifically what You wrote the constructor should be:
Person();
in .h
and
Person::Person()
{
m_h = 1;
m_w = 5;
}
in .cpp.
If You need more detailed description of using include, I have already written a big part of it, so don't hesitate to ask.

C++ unresovled external symbol link error related with name mangling?

all
i created a static lib project with VS 2010 sp1, and simply defined a class with a member function (code snippet):
.h:
namespace puphttp{
class CRequester
{
public:
void RequesterUpdate();
};
}
.cpp:
#include "StdAfx.h"
#include "Requester.h"
#include <iostream>
using namespace std;
namespace puphttp{
void CRequester::RequesterUpdate()
{
cout<<"updating";
}
}
at last i linked the lib file and tried to invoke the following code:
puphttp::CRequester c;
c.RequestUpdate();
the following link error occur as i compile:
error LNK2001: unresolved external symbol "public: void __cdecl puphttp::CRequester::RequestUpdate(void)" (?RequestUpdate#CRequest#puphttp##QEAAXXZ)
then i used dumpbin to check the actual function name in my lib, it's:
(?RequestUpdate#CRequest#puphttp##QAEXXZ)
so the difference is QEAAXXZ vs QAEXXZ, i didn't have time to get into name mangling rule yet, so any quick answer? really much appreciated.

Unresolved External Symbol C++

I have read this informative stackoverflow question regarding unresolved external symbols, but I am still not sure how to solve my issue.
Within Visual Studio 2012, I have a solution consisting of multiple projects, one of which is a static library called common. Each project that produces an executable consists of a header and associated cpp file of all global functions used throughout that specific program, called programglobals. In the process of developing one of these projects, I started duplicating some of this code from one project's programglobals to another. Now that I have completed all the projects, I want to extract the duplicate code into a associated header and cpp file within the common library, but I believe I might be referencing them incorrectly, which is producing these unresolved external symbol errors
Here is a dumbed down example of what I am currently attempting.
Common Library Files
//solutionglobals.h
void commonFunction();
//solutionglobals.cpp
void commonFunction() {
int asdf;
}
Project A Files
// programglobals.h
#include "../common/solutionglobals.h
void functionUsedInProjectA();
// programglobals.cpp
void functionUsedInProjectA() {
int x;
}
// output.h
#include "programglobals.h"
void asdfA();
// output.cpp
void asdfA() {
int x;
functionUsedInProjectA();
commonFunction();
}
Project B Files
// programglobals.h
#include "../common/solutionglobals.h
void functionUsedInProjectB();
// programglobals.cpp
void functionUsedInProjectB() {
int x;
}
// output.h
#include "programglobals.h"
void asdfB();
// output.cpp
void asdfB() {
int x;
functionUsedInProjectB();
commonFunction();
}
Any reference to commonFunction() results in an unresolved external symbol error.
Thanks!
You will have to specify in your executable projects that they reference the static lib. May be http://msdn.microsoft.com/en-us/library/vstudio/ms235627%28v=vs.110%29.aspx#uselibinapp helps (lower third of the article).
Before you can use the math routines in the static library, you must
reference it. To do this, open the shortcut menu for the MyExecRefsLib
project in Solution Explorer, and then choose References. In the
MyExecRefsLib Property Pages dialog box, expand the Common Properties
node, select Framework and References, and then choose the Add New
Reference button.
The linker cannot 'see' your function and as such thinks that it does not have an external symbol referencing it, hence the error.
You must #pragma comment(lib, [library here]) to reference the external function.
The following code can be used to reproduce this error:
[header file- test.h]:
#include "StdAfx.h"
void someOtherFunction();
void someFunction(string thisVar);
[code file- test.cpp]:
#include "StdAfx.h"
#include "test.h"
void someOtherFunction()
{
printf("Hello World!");
}
[function body for someFunction(string thisVar) is missing!]

Linking failure within solution

EDIT: I know there are similar questions, but I cannot find an answer to a following issue: Why the methods inside the class are working correctly and outside are not.
I've got a weird problem in my project which I'm developing in MSVC++ 2012. My project consists of different modules of code. The important modules from the problem's point of view is a library and the GUI. They exist as different projects in the same solution.
I have some methods in the library which are part of the classes (in this case Calibration3D):
void Calibration3D::load(const std::string &path)
I use it without problems when I need it in the GUI, however I need to use a following method (outside the class):
void xxxyyy()
But when I'm trying to use that function (outside the class but in the same namespace) I get a following error:
1>project_xml.obj : error LNK2001: unresolved external symbol "void __cdecl cci::xxxyyy(void)" (?xxxyyy#cci##YAXXZ) 1>D:\praca_pw\cci\build-msvc2012\x64\Release\\ccigui.exe : fatal error LNK1120: 1 unresolved externals
Anybody knows how to solve it?
When I have a header file like this:
namespace xyz {
void foo();
class bar { ... };
}
then I write the cpp file like this:
#include "xyz.h"
namespace xyz {
void foo() { ... }
bar::bar() { ... }
}
This means I have to type a lot less and make fewer mistakes with regard to namespaces.
OK, solved, it seems that when a method is defined inside the namespace in header file, it should also be defined explicitly as part of namespace in implementation file, in this case:
cci::xxxyyy()
{
...
}
will work and
xxxyyy()
{
...
}
will not.

How to use 2 C libs that export the same function names [duplicate]

This question already has answers here:
Closed 13 years ago.
Duplicate of the following question: C function conflict
Hi,
in my current project I have to use some kind of interface lib. The function names are given by this interface, what this functions do is developers choice. As far as I can tell a project shall use this functions and when it comes to compiling you choose the lib and with it the functionality. What I try to do is to use an existing lib and my lib at the same time by wrapping the other and call it in mein functions:
otherlib:
int function1 (int a) {
// do something
}
mylib:
int function1 (int a) {
//my code here
otherlib::function1(a);
}
Problem is I don't have access to the other lib and the other lib doesn't have any namespaces. I already tried
namespace old {
#include "otherlib.h"
}
and then call the old function by old::function1 in my function. This works as long as it's only header file. The lib exports it's symbol back into global space. Also something like
namespace new {
function1 (int a) {
::function1(a);
}
}
didn't work. Last but not least I tried ifdefs and defines suggested here
but I wasn't successful.
Any ideas how to solve this? Thanks in advance.
EDIT: I neither have access to the old lib nor the project both libs shall be used in.
EDIT2: at least the old lib is a static one
Namespaces in C solved using library names prefixes like:
libfoo --> foo_function1
libbar --> bar_function1
These prefixes are actual namespaces. so if you write libbar
int bar_function1(int a) {
function1(a);
}
This is the way to solve problems.
C has namespaces --- they just called prefixes ;)
Another option is to do various dirty tricks with dynamic loading of libraries like:
h1=dlopen("libfoo.so")
foo_function1=dlsym(h1,"function1")
h2=dlopen("libbar.so")
bar_function1=dlsym(h2,"function1")
It seems as if the other lib is C and your code is C++. You can be running into a mangling problem (C++ compilers mangle the symbols -- add extra stuff in the symbol name do differentiate overloads and the like).
If the library is pure C you can try:
extern "C" { // disable mangling of symbol names in the block
#include "otherlib.h"
}
namespace new_lib { // new is a reserved word
int function1( int a ) {
::function1(a);
}
}
I have not tried it. Also consider providing the error messages you are getting.
Another option would be (if the library is dynamic) dynamically loading the lib and calling the function. In linux (I don't know about windows) you can use dlopen to open the library, dlsym to obtain the symbol and call it:
// off the top of my head, not tried:
int function1( int a )
{
int (*f)(int); // define the function pointer
void * handle = dlopen( "library.so" );
f = dlsym( handle, "function1" );
f( a ); // calls function1(a) in the dynamic library
}
In this case, as you are not linking against the library you won't get a symbol conflict, but then again, it is only valid for dynamic libraries and it is quite cumbersome for regular usage.
UPDATE
If your users will not use 'otherlib' directly (they won't include their headers) and they will be only C++, then the first approach could be possible (even if horrible to read):
// newlib.h
namespace hideout {
int f( int a );
}
using namespace hideout; // usually I would not put this on the header
// newlib.cpp
extern "C" { // if otherlib is C, else remove this line
#include "otherlib.h"
}
namespace hideout {
int f( int a ) { return ::f( a*2 ); }
}
// main.cpp
#include "newlib.h"
int main()
{
std::cout << f( 5 ) << std::endl;
}
How does it work? User code will only see a declaration of function1 (in the example f()) as they are not including otherlib.h. Inside your compilation unit you see the two declarations but you differentiate through the use of the namespace. The using statement in the header does not bother you as you are fully qualifying in your cpp. The user main.cpp will include only your header, so the compiler will only see hideout::f, and will see it anywhere due to the using statement. The linker will have no problem as the C++ symbol is mangled identifying the real namespace:
// g++ 4.0 in macosx:
00002dbe T __ZN7hideout9function1Ei // namespace hideout, function1 takes int, returns int
00002db0 T _function1
If user code will include both your header and otherlib.h then it will have to qualify which function it wants to call.
If you're really desperate, you could write a wrapper library that uses namespaces or prefixes or allows for the dlsym trick. This wrapper library would need to be dynamically linked (to avoid symbol conflicts). The dynamic library could then safely have the old static library embedded in it. Just make sure you don't export the symbols from the static library when making the dynamic wrapper library.
You can't resolve this at link time, so you'll need to resolve it at runtime via dynamic libraries. The symbol for those functions is essentially baked it once the library has been generated. If two libraries export the same symbol, they cannot both be linked with statically.