We have a project with a static library and an associated executable test project.
In the static library we #include "Poco/UnbufferedStreamBuf.h" and derive from it to implement a custom streambuf.
We then attempt to link the static library and the import library PocoFoundationd.lib into the executable, and get a linker error about multiply defined symbols:
3>PocoFoundationd.lib(PocoFoundationd.dll) : error LNK2005: "public: __thiscall Poco::BasicUnbufferedStreamBuf<char,struct std::char_traits<char> >::BasicUnbufferedStreamBuf<char,struct std::char_traits<char> >(void)" (??0?$BasicUnbufferedStreamBuf@DU?$char_traits@D@std@@@Poco@@QAE@XZ) already defined in mylib.lib(my_custom_ostream.obj)
3>PocoFoundationd.lib(PocoFoundationd.dll) : error LNK2005: "public: virtual __thiscall Poco::BasicUnbufferedStreamBuf<char,struct std::char_traits<char> >::~BasicUnbufferedStreamBuf<char,struct std::char_traits<char> >(void)" (??1?$BasicUnbufferedStreamBuf@DU?$char_traits@D@std@@@Poco@@UAE@XZ) already defined in mylib.lib(my_custom_ostream.obj)
3>PocoFoundationd.lib(PocoFoundationd.dll) : error LNK2005: "protected: static int __cdecl Poco::BasicUnbufferedStreamBuf<char,struct std::char_traits<char> >::charToInt(char)" (?charToInt@?$BasicUnbufferedStreamBuf@DU?$char_traits@D@std@@@Poco@@KAHD@Z) already defined in mylib.lib(my_custom_ostream.obj)
It turns out this is because the compiler generates symbols for the inline template in the static library. The import library for PocoFoundation.dll also has its own copy of the symbol, and there's a conflict.
I was able to work around this by adding Foundation_API to the declaration of BasicUnbufferedStreamBuf in Poco/UnbufferedStreamBuf.h. That change makes sense to me, as all definitions of the base class are now either dllexport or dllimport, and all compilation units see the same definition.
This works on Windows, but I haven't yet checked how a Linux build behaves (does Foundation_API expand to anything on Unix systems?).
I'll try this as well and post back with a small patch if it appears to work. Makes sense?
We have a project with a static library and an associated executable test project.
In the static library we
#include "Poco/UnbufferedStreamBuf.h"and derive from it to implement a custom streambuf.We then attempt to link the static library and the import library PocoFoundationd.lib into the executable, and get a linker error about multiply defined symbols:
It turns out this is because the compiler generates symbols for the inline template in the static library. The import library for PocoFoundation.dll also has its own copy of the symbol, and there's a conflict.
I was able to work around this by adding
Foundation_APIto the declaration ofBasicUnbufferedStreamBufinPoco/UnbufferedStreamBuf.h. That change makes sense to me, as all definitions of the base class are now eitherdllexportordllimport, and all compilation units see the same definition.This works on Windows, but I haven't yet checked how a Linux build behaves (does
Foundation_APIexpand to anything on Unix systems?).I'll try this as well and post back with a small patch if it appears to work. Makes sense?