Reputation: 811
I have inherited a Linux project that I need to port to Windows and Visual Studio. I have setup the same project structure as was the case in Linux but I find the structure a bit strange (maybe it is all good in Linux) and I believe that's what's causing the LNK4217 (locally defined symbol 'symbol' imported in function 'function') and C4273 ('function' : inconsistent DLL linkage) warnings I receive. I would like some advice on how to re-structure the project or change the code to avoid these warnings. Basically this is what I have:
The part that I find strange and what I believe causes the LINK4217 and C4273 warnings is that both the Foo and Bar library contain the header and source file for the class MyClass
(the warnings mention this class):
//MyClass.h
class BAR_API MyClass
{
//Methods etc.
}
Where BAR_API
is defined as __declspec(dllexport)
in the Bar library while in the Foo library it is __declspec(dllimport)
according to:
#ifdef BAR_EXPORTS
#define BAR_API __declspec(dllexport)
#else
#define BAR_API __declspec(dllimport)
#endif
How do you propose I change this? Would it help to move MyClass to its own library and have Foo and Bar include it or change so that BAR_API
is defined as nothing instead of __declspec(dllimport)
in the Foo library?
Upvotes: 1
Views: 1940
Reputation: 169
Let's see what you have here
1. Foo.dll
that defines MyClass
and exports it
2. Bar.dll
that depends on Foo.dll
, but also defines MyClass
- and this is the source of ambiguity that confuses your linker.
The right thing, to my understanding, is to:
MyClass
in Foo.dll
(since Bar.dll
already depends on it) and export MyClass
using __declspec(dllexport)
in Foo.dll
's MyClass
declaration.#include
header file that declares MyClass
(where it will be specified as imported using __declspec(dllimport)
) where appropriate in the Bar.dll
's .cpp
files; however, do not include the .cpp
file that implements MyClass
.BAR_API
(which in this case should be renamed to FOO_API) helps you achieve this by being defined as either dllexport
or dllimport
based on whether BAR_EXPORTS
(which in this case should be renamed to FOO_EXPORTS
) is defined. You should #define FOO_EXPORTS
in every source file in the Foo project either by setting compiler command line parameter or by #including common header that #defines FOO_EXPORTS
in every .cpp
file in the Foo project (but not in the Bar project).
This way both Foo.dll and Bar.dll will use MyClass from the Foo.dll.
HTH
Upvotes: 2