Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

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

Posted on 2014-01-08
5
Medium Priority
?
605 Views
Last Modified: 2014-01-13
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
0
Comment
Question by:Zoppo
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
5 Comments
 
LVL 35

Assisted Solution

by:sarabande
sarabande earned 2000 total points
ID: 39767911
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.

Sara
0
 
LVL 31

Author Comment

by:Zoppo
ID: 39775898
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
0
 
LVL 35

Accepted Solution

by:
sarabande earned 2000 total points
ID: 39776217
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.

Sara
0
 
LVL 31

Author Comment

by:Zoppo
ID: 39778489
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
0
 
LVL 31

Author Closing Comment

by:Zoppo
ID: 39778491
No solution possible. I want to assign the points to Sara anyway for the good explanation ...
0

Featured Post

The top UI technologies you need to be aware of

An important part of the job as a front-end developer is to stay up to date and in contact with new tools, trends and workflows. That’s why you cannot miss this upcoming webinar to explore the latest trends in UI technologies!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you’re thinking to yourself “That description sounds a lot like two people doing the work that one could accomplish,” you’re not alone.
Q&A with Course Creator, Mark Lassoff, on the importance of HTML5 in the career of a modern-day developer.
An introduction to basic programming syntax in Java by creating a simple program. Viewers can follow the tutorial as they create their first class in Java. Definitions and explanations about each element are given to help prepare viewers for future …
Starting up a Project

721 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question