This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: dllexport and inline methods


I wrote:
[...]
>     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};
>     };
[...]
> Notice that inline methods for class A and class B are NOT
> being inlined inside the library (and the compiler does tell us
> why in the case of B::fb()).
[...]

For those of us that would like to be able to build optimised
shared libraries under Windows, without having to rewrite all
code to look like class C above, I think I have found a work-
around.

An off-list reply to my query suggested I play with .def files.
I had previously discarded using def files as being too hard
with C++.  But it turns out not to be so hard.

First step:

  Stop using dllexport and dllimport with mingw/gcc.  Leave
  your macros in place so they will work with msvc builds, but
  under gcc set to them to blank.

  Add this to your linker commands: -Wl,--export-all-symbols
  (the -Wl, prefix needed if passing through gcc/g++)

  Make sure your build produces its own def file:
    -Wl,--output-def=mylib.def

This works with my current project, and it seems that this step
is all that is necessary - just not very neat.  I expect it
will be easier to leave this configuration in place while the
library is still under active development.

gcc happily compiles the library, including inlining where
it can.  I ran across a few instances where using class A style
code did not resolve when using the library.  I moved the few
instances of those to class B (out-of-class inline) and those
problems went away.  (No idea why, I thought class A and class
B should be effectively identical.)

QUESTION: Does anyone know of any down-side to using
--export-all-symbols other than the increase in interface
size (and resulting startup impact)?


Second step:

I just tried out the next step in the process, which is to take
the .def file produced above (by the --output-def) and filter
it to include only the necessary symbols.

You can then use the filtered result to rebuild your libraries
using -Wl,mydef.def in place of -Wl,--export-all-symbols.  The
result being a smaller and more efficient interface (we hope).

I'd like to automate the .def file filtering, which should be
easy enough on the first library using namespaces, but I'm
creating a project of multiple libraries all of which work over
the same namespace so filtering could get more difficult.  But
it's still easier to filter the result from step one than to
write a new one from scratch.


I'm guessing other complications may arise, but I'm hoping that
they can be resolved.  The above, so far, seems to be working
with the two libraries on my current project - about 30 classes
or maybe a bit more.  So it looks promising.  I have read that
strange things may happen with exception classes if you don't
get the export exactly right, so I have more testing to do.


I don't know what dllexport is really doing inside gcc, it
appears to have taken on a meaning above that of "export this
this symbol" and gives peculiar attributes to functions that
are not always appropriate.

-- 
Geoff Worboys
Telesis Computing Pty Ltd


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]