Link to home
Start Free TrialLog in
Avatar of Zoppo
ZoppoFlag for Germany

asked on

Problem linking a LIB, a DLL and a EXE together in VisualStudio 2010

Hi everybody,

I encountered a problem with a project which contains one LIB, one DLL and one EXE in a way the DLL uses functions from the LIB, the EXE uses function from the LIB and the DLL.

In this case it seems all symbols exported by the LIB are linked twice, once into the DLL, once into the EXE. This at least blows up the resulting binaries. Further this causes i.e. global variables from the LIB aren't really global, there's one instance in the DLL and another one in the EXE, so the use of global variables from the LIB doesn't work as expected.

Does anyone know if there's a way to workaround this? Since for the DLL a LIB is built too maybe it's possible to link the other LIB into it - any ideas?

You can follow these steps if you want to reproduce the problem:

- Create a solution with a console application (below called LibTest), a LIB (BaseLib) and a DLL (ExtLib)
- In 'Common Properties->Framework and References' add the LIB as reference in the DLL and add both the LIB and the DLL as reference in the EXE.
- Implement the following functions in the appropriate files:
// BASE.H
#include <ostream>

extern int baseval;
extern void foo( std::ostream& os );

// BASE.CPP
#include "Base.h"

int baseval = 42;

void foo( std::ostream& os )
{
	os << "foo() called, &foo = 0x" << std::hex << &foo << ", &baseval = 0x" << &baseval << std::endl;
}

Open in new window

// EXTLIB.H
#include <iostream>

#ifdef EXTLIB_EXPORTS
#define EXTLIB_API __declspec(dllexport)
#else
#define EXTLIB_API __declspec(dllimport)
#endif

EXTLIB_API void bar( std::ostream& os );

// EXTLIB.CPP
#include "ExtLib.h"
#include "../BaseLib/Base.h"

EXTLIB_API void bar( std::ostream& os )
{
	foo( os );
}

Open in new window

// LIBTEST.CPP
#include <iostream>
#include <tchar.h>

#include "../BaseLib/Base.h"
#include "../ExtLib/ExtLib.h"

int _tmain(int argc, _TCHAR* argv[])
{
	foo( std::cout );
	bar( std::cout );
	return 0;
}

Open in new window

(I unset the 'Use precompiled header' setting, you can do so too or add #include "stdafx.h" to every CPP file).

When I run this program the output is like
foo() called, &foo = 0x00C910A0, &baseval = 0x00C93018
foo() called, &foo = 0x5AD21080, &baseval = 0x5AD23010

Open in new window

When I change the DLL to build to a LIB instead the same doesn't happen, there the output looks like
foo() called, &foo = 0x00AE10E0, &baseval = 0x00AE3018
foo() called, &foo = 0x00AE10E0, &baseval = 0x00AE3018

Open in new window

Thanks in advance,

best regards,

ZOPPO
SOLUTION
Avatar of sarabande
sarabande
Flag of Luxembourg image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Zoppo

ASKER

Hi Sara,

thanks for the comment. And yes, that's even what I thought.

Unfortunateley we exactly want to avoid the need to create a DLL for each library.

I thought there maybe could be a possibility to link the LIB into the "Import Library" LIB file which is created with the DLL for implicit linking. Thus I think it would be possible to avoid those duplicate symbols.

Do you think this is possible?

Best regards,

ZOPPO
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Zoppo

ASKER

Thanks again. And yes, you're right, I managed to link the LIB into the DLL's Import Library so the EXE doesn't need to link the LIB itself, but there still are two copies of the symbols, one within the DLL and one with its Import Library. So it seem's there's no way to use a static LIB the way I like :o(

Best regards,

ZOPPO
Avatar of Zoppo

ASKER

No solution possible. I want to assign the points to Sara anyway for the good explanation ...