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:
#include <ostream>

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

#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

#include <iostream>

#define EXTLIB_API __declspec(dllexport)
#define EXTLIB_API __declspec(dllimport)

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

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

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

Open in new window

#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,

LVL 32
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

a lib is technically only a collection of object files. because of that if you use the lib in two executables, you would necessarily have the symbols twice and any static or global symbol has an instance in the exe or dll. that is same as you would add the same source file to two projects where you also get all symbols twice.

if you want to change that you have to turn the lib into a dll or you write wrappers in the dll for all functions of the lib and export them.

i am currently working on a project with about 50 dll's and no lib. we have both methods that either a bundle of functions has moved to a new dll, or that a function needed in a second dll was exported from a dll.

the visual studio references would add nothing to that, as far as i know. they are for "intellisense" purposes only.

ZoppoAuthor Commented:
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,

the 'import library' added to a dll actually is wrapper code, a bundle of functions which have the same interface as the original dll functions, but have no code beside of calling into the original dll function.

for a function in a static lib that should be shared, you would need to write the wrapper code yourself. you would need a dll which is 'host' of the static library and the dll would link against it. you would need code for the wrappers and a second library (project) that contains the wrappers. so actually you do the same as you would get automatically when turning the lib to a dll. the only advantage i see is that you could have one dll for multiple small(er) libraries and therefore less issues if the functions were mutually dependent on each other.

i worked with static libraries in the past but found them inconvenient when the project grows. in current projects i add functions to dlls and export them. or if i have a bundle of functions, i put them into a class and export the class. the important question then is which dll is suitable to take the function/class. for example if i have a function in dll1 that i need in dll2, i firstly check whether dll2 was built prior to dll1 in the build order. if that isn't the case i have to move the function (or class) to dll3 where both dll1 and dll2 can be dependent on. after that the function was exported and can used both by dll1 and dll2.


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ZoppoAuthor Commented:
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,

ZoppoAuthor Commented:
No solution possible. I want to assign the points to Sara anyway for the good explanation ...
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.