On 11/20/18 9:35 AM, John Maddock via Boost-users wrote:
On 19/11/2018 19:07, John Maddock wrote:
OK - due to some sleuthing on the part of one of the auxiliary maintainers of the boost serialization library, it's seems that the problem is that
BOOST_SYMBOL_IMPORT is not defined to be __attribute__((__dllimport__)) under MINGW and that is the source of the problem.
That's not true, gcc.hpp has:
# define BOOST_SYMBOL_EXPORT __attribute__((__dllexport__)) # define BOOST_SYMBOL_IMPORT __attribute__((__dllimport__))
when _Win32 is defined.
And if I modify config_info.cpp to print these out then I see:
BOOST_SYMBOL_EXPORT =__attribute__((__dllexport__)) BOOST_SYMBOL_IMPORT =__attribute__((__dllimport__)) BOOST_SYMBOL_VISIBLE =__attribute__((__visibility__("default")))
Which looks good to me.
I *think* I may have twigged on to what's happening here.
To recap, msvc when exporting a symbol from a dll mangles the name with a __imp_ prefix. Further it performs "early name mangling" - ie the compiler does it and the mangled name for the export ends up in the object file.
GCC normally does not mangle names when changing visibility, instead it stores "something" in the object file to tell the linker to make the symbol visible. On windows it's the *linker* that takes this information and creates an alias with the appropriately mangled name when building the dll. That means that the object files do not contain records with the __imp_ prefix, only the finished dll.
However, when importing, since dllimport suggests import from a dll, gcc mangles the name immediately so that the linker knows to look for a __imp_ prefixed name.
Now look at what you're doing in these failing tests: you're mixing object files *in the same executable* some of which are using dllexport and some using dllimport and now we have a mismatch with dllimport implying the __imp_ prefix but there are no matching __imp_ prefixed records in the object files.
I think this is a bug in your tests, albeit a very obscure one. To fix you would need to either:
* Use dllexport consistently throughout an executable: ie if a class is dllexport in one object file in the dll or exe, then it should be dllexport in *all the object files in that dll/exe*, including in object files that only use those symbols not define them.
Right. I don't think I'm doing this - but I'll double check.
* Don't export these symbols: so far as I can tell, the exported symbols are never imported from anything (since we never build a dll with them) so exporting is completely redundant in this case. You may still need BOOST_SYMBOL_VISIBLE on them on for *nix systems, not sure about that though.
* Or, put these exported symbols in a dll and link the test program to it.
I believe that that is what I'm doing. Again, we'll double check. This is the test test_dll_exported...
Hopefully that makes sense, John.
I'm sure it does. But not to me yet. I'll spend some time investigating this with the information you've provided. Note that in the test there is dll_polymorphic_derived2. This exports a couple of functions. But it depends on dll_polymorphic_base and imports some symbols from that. In C++, the class derived2 inherits from the class base. So within the same module we're both exporting and importing albeit different symbols. The normal windows tests seem to be fine with this. I'll try to figure out what mingw does differently. Thanks for your help with this. I couldn't do it by myself. Robert Ramey