The editing that I did in another post did not seem to be perceived, and in any case it seems that some additional clarity may be appropriate, so I am posting the details that I posted to another forum. In the class C code below, this problem works - export only elements that are not part of the composition, not the entire class. As noted in the comments elsewhere, __declspec(dllexport) and __attribute__((dllexport)) equivalent.
test.hpp
class __declspec(dllexport) A { public: int fa() { return m; } int ga(); private: int m{0}; }; class __declspec(dllexport) B { public: int fb(); int gb(); private: int m{0}; }; inline int B::fb() { return m; } class C { public: int fc() { return m; } __declspec(dllexport) int gc(); private: int m{0}; };
test.cpp
#include "test.hpp" int A::ga() { return (fa() + 1); } int B::gb() { return (fb() + 1); } int C::gc() { return (fc() + 1); }
If you compile this using the options: -std=c++11 -O2 -S -Winline (using mingw / ming64 with gcc v4.7.2 or v4.8.0), you can see that the collector created for the ga library functions is gb and gc are as follows:
ha:
subq $40, %rsp .seh_stackalloc 40 .seh_endprologue call _ZN1A2faEv addl $1, %eax addq $40, %rsp ret
GB:
subq $40, %rsp .seh_stackalloc 40 .seh_endprologue call _ZN1B2fbEv addl $1, %eax addq $40, %rsp ret
ds:
.seh_endprologue movl (%rcx), %eax addl $1, %eax ret
and you will get warnings:
warning: function 'int B::fb()' can never be inlined because it uses attributes conflicting with inlining [-Winline]
warning: inlining failed in call to 'int B::fb()': function not inlinable [-Winline] (called from B::gb())
Note that there were no warnings that fa is not embeddable (which, I think, was expected). But also note that ga, gb, and gc are all library functions. No matter what you might think about whether the built-in functions themselves should be exported, there are no good reasons why the built-in strings cannot be built into the library. Therefore, I consider this a bug in the compiler.
Take a look at the well-studied code and see how much you find that only explicit members are exported. For example, those few boost parts that compile into a library (such as regex) use the class A method, which means that many access functions are not built into the library.
But, all that is aside, the answer at the moment is the class C method (it is obvious that in real code this must be enclosed in a macro in order to switch between export and import, as usual at the class level).