On 7/27/2015 5:00 AM, Ruben Van Boxem wrote: > 2015-07-27 8:54 GMT+02:00 Edward Diener <eldlistmaili...@tropicsoft.com > <mailto:eldlistmaili...@tropicsoft.com>>: > > On 7/24/2015 11:13 AM, Ruben Van Boxem wrote: > > 2015-07-24 17:03 GMT+02:00 Edward Diener > <eldlistmaili...@tropicsoft.com > <mailto:eldlistmaili...@tropicsoft.com> > > <mailto:eldlistmaili...@tropicsoft.com > <mailto:eldlistmaili...@tropicsoft.com>>>: > > > > On 7/24/2015 8:54 AM, Riot wrote: > > > Where are you defining your template, in the header or the > source? You > > > may need to explicitly instantiate. > > > > The template is being defined in the YY.cpp source file. > > > > > > Could you send example files displaying the issue? It makes it easier to > > reproduce and debug the issue. > > Here are the files and the command lines. All files should be placed in > the same source directory with a 'debug' sub-directory where everything > will be built. You need to have the mingw-64 gcc-5.1 32-bit bin > directory in your PATH and you need to be in the source directory when > executing the commands. I am only concerned with problems linking and > not with running the result. > > First the header and source file to be built into a shared library: > > Header file exception_cl.hpp > > #ifndef EXCEPTION_CL_HPP > #define EXCEPTION_CL_HPP > > #include <exception> > > #if defined(BUILD_SL) > #define CLASS_DECL __attribute__((__dllexport__)) > #else > #define CLASS_DECL __attribute__((__dllimport__)) > #endif > > class __attribute__((__visibility__("default"))) exception_cl : > public virtual std::exception > { > private: > char m_buffer[128]; > public: > int code; > > CLASS_DECL exception_cl(int) ; > virtual CLASS_DECL ~exception_cl() throw() ; > virtual CLASS_DECL const char * what() const throw() ; > }; > > #endif // EXCEPTION_CL_HPP > > Source file exception_cl.cpp > > #define BUILD_SL > #include "exception_cl.hpp" > > CLASS_DECL > exception_cl::exception_cl(int i) : > code(i) > { > m_buffer[0] = '\0'; > } > > CLASS_DECL > exception_cl::~exception_cl() throw() {} > > CLASS_DECL const char * > exception_cl::what( ) const throw() { > return m_buffer; > } > > The command for compiling the source file is: > > g++ -ftemplate-depth-128 -Wno-unused-local-typedefs > -ftrack-macro-expansion=0 -O0 -fno-inline -Wall -g -march=i686 -m32 > -fvisibility-inlines-hidden -fvisibility=hidden -c -o > ".\debug\exception_cl.o" "exception_cl.cpp" > > The command for linking the object file to a shared library called > lib-excl-mgw51 is: > > g++ "-Wl,--out-implib,.\debug\lib-excl-mgw51.dll.a" -o > ".\debug\lib-excl-mgw51.dll" -shared -Wl,--start-group > ".\debug\exception_cl.o" -Wl,-Bstatic -Wl,-Bdynamic -Wl,--end-group > -g -march=i686 -m32 > > These commands succeed without problems in creating the shared library > and the import library in the 'debug' subdirectory. > > Now the source file to be built into an executable, which uses the > exception_cl class from the shared library. I call the source file > 'throw_exception_cl.cpp': > > #include "exception_cl.hpp" > template<class E> void throw_exception(E const & e) { throw e; } > int main(int argc,char * argv[]) > { > if (argc > 1) > { > #if 1 > throw_exception(exception_cl(0)); > #else > throw exception_cl(0); > #endif > } > return 0; > } > > The command for compiling the file is: > > g++ -ftemplate-depth-128 -Wno-unused-local-typedefs > -ftrack-macro-expansion=0 -O0 -fno-inline -Wall -g -march=i686 -m32 -c > -o ".\debug\throw_exception_cl.o" "throw_exception_cl.cpp" > > This command succeeds in creating the object file in the 'debug' > subdirectory. > > Now the command to link the source file's object file into an > executable: > > g++ -Wl,-R -Wl,".\debug" -Wl,-rpath-link -Wl,".\debug" -o > ".\debug\te.exe" -Wl,--start-group ".\debug\throw_exception_cl.o" > ".\debug\lib-excl-mgw51.dll.a" -Wl,-Bstatic -Wl,-Bdynamic > -Wl,--end-group -g -march=i686 -m32 > > This command fails with the messages: > > .\debug\throw_exception_cl.o: In function `ZN12exception_clC1ERKS_': > > C:\Programming\VersionControl\modular-boost\libs\serialization\src/exception_cl.hpp:12: > undefined reference to `vtable for exception_cl' > > C:\Programming\VersionControl\modular-boost\libs\serialization\src/exception_cl.hpp:12: > undefined reference to `vtable for exception_cl' > collect2.exe: error: ld returned 1 exit status > > If in the source file immediately above, the "#if 1" line is changed to > "if 0", the link command succeeds without error. But I need it to > succeed as is. > > Please realize that this is all a much boiled down example of the actual > problem that is occurring with mingw-64 gcc-5.1 32-bit compile, but it > shows the problem itself that is occurring in the actual code. The > problem also occurs in the other latest mingw-64 gcc-4.9.2 and 4.8.5 32 > bit releases. > > > This is exactly what is necessary to fix any problem: a smallest > compilable source code example that shows the problem. Thanks for this. > > The issue is that you are (or GCC is) using an implicitly defined copy > constructor, which is not exported. There are two fixes: > 1. Make the whole class CLASS_DECL, instead of each function separately > (and remove the visibility attribute which I believe is not useful on > Windows) > class CLASS_DECL exception_cl /*...*/ > > 2. Add an explicitly export/imported copy constructor which is probably > necessary anywas because you're using a char array (if you used > std::array<char,128> or just std::string or some fixed-length short > string class, there would be no need to memcpy anything) > > Unfortunately, c++filt seems to be unable to unmangle the undefined > reference name, or I would have gotten to this conclusion a lot sooner.
Bravo ! Thank you very much ! > > Cheers, > > Ruben > > > Any help or suggestions for solving this problem are much appreciated. > > > > > Thanks, > > > > Ruben > > > > > > > > > > On 24 Jul 2015 13:31, "Edward Diener" > > <eldlistmaili...@tropicsoft.com > <mailto:eldlistmaili...@tropicsoft.com> > > <mailto:eldlistmaili...@tropicsoft.com > <mailto:eldlistmaili...@tropicsoft.com>> > > > <mailto:eldlistmaili...@tropicsoft.com > <mailto:eldlistmaili...@tropicsoft.com> > > > <mailto:eldlistmaili...@tropicsoft.com > <mailto:eldlistmaili...@tropicsoft.com>>>> > wrote: > > > > > > Before attempting to reduce my code to a small enough > example > > to post > > > here in its entirety I will give a description of the > problem > > to see if > > > anyone has encountered it in general. The problem is > purely a > > linker > > > problem. > > > > > > I have an exported class in a shared library, called > it XX in > > header > > > file XX.hpp. From an executable's source file, called > it YY.cpp I > > > include the class's header file where the class will > show as > > imported > > > and in the code in the source file I throw an > exception with > > an instance > > > of the class, as in: > > > > > > throw XX(some_constructor_parameters); > > > > > > This compiles and links without error. > > > > > > If instead I use a template to throw an exception, > such as: > > > > > > template<class E> void throw_exception(E const & > e) { > > throw e; } > > > > > > and then invoke it from my executable as: > > > > > > throw_exception(XX(some_constructor_parameters)); > > > > > > I receive a linker error of the form: > > > > > > YY.o: In function `SomeDecoratedName': > > > XX.hpp:27: undefined reference to `vtable for XX' > > > XX.hpp:27: undefined reference to `vtable for XX' > > > > > > I realize that this is not a complete example but before > > reducing my > > > code to the least possible example which will > reproduce this > > problem I > > > thought I would ask if anyone has encountered anything > like > > it, or has > > > any idea why using a template causes a linker error > whereas > > not using > > > the template links would link without any problems. ------------------------------------------------------------------------------ _______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public