Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. Is it possible to create a dll without dllexport?
QtWS25 Last Chance

Is it possible to create a dll without dllexport?

Scheduled Pinned Locked Moved Solved C++ Gurus
dllexporttemplate libmingw weirdnessmingw dll
14 Posts 3 Posters 6.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    Chris Kawa
    Lifetime Qt Champion
    wrote on 12 Jun 2016, 17:05 last edited by
    #2

    I'm not sure if I got you right.
    You have a "main" class and it inherits from a class defined in a shared library, and this caused the size of the executable to shrink. Is that right? Sounds logical. What's the issue?

    K 1 Reply Last reply 12 Jun 2016, 18:15
    0
    • C Chris Kawa
      12 Jun 2016, 17:05

      I'm not sure if I got you right.
      You have a "main" class and it inherits from a class defined in a shared library, and this caused the size of the executable to shrink. Is that right? Sounds logical. What's the issue?

      K Offline
      K Offline
      koahnig
      wrote on 12 Jun 2016, 18:15 last edited by
      #3

      @Chris-Kawa

      Not exactly.

      More like this here:

      First classes level1 are exprted to dll1

      class DLL1SHARED_EXPORT level1_1
      {
      };
      

      Second classes level2 are exported to dll2

      class DLL2SHARED_EXPORT level2_1 : public level1_1
      {
      };
      

      Finally classes level_main are initially statically linked with code in program main.

      class level_main_1: public level2_1
      {
      };
      

      main.exe has sized of about 1.2 MB as long as the compilation is done with all those "level_main_" classes through a project template "app" and one .pro file.
      Duplication of .pro-file, renaming in one "TEMPLATE = app" -> "TEMPLATE = lib". Also ensured that only the file with "TEMPLATE = app" holds the source file with "program main(...)". LIBS += statement added to point to location of .lib (all the resulting dll).
      The other .pro holds all remaining code files.

      Since I did NOT add so far the macro "DLL_MAIN_SHARED_EXPORT" or something to the definition of classes starting with "level_main_" I did expect that the size of the resulting .exe is statically linked and has a similar size of 1.2 MB.

      However, apparently there is a dll already created and the exe size has dropped to 50 kB of .exe.

      The only explanation I have at the moment is that a dynamic lib is default for "TEMPLATE=LIB" and I did not bother to change to make the library static through qmake. However, I thought that I would need also the macro "DLL_MAIN_SHARED_EXPORT" mimic for actually creating a dll.

      Vote the answer(s) that helped you to solve your issue(s)

      K 1 Reply Last reply 12 Jun 2016, 18:23
      0
      • C Offline
        C Offline
        Chris Kawa
        Lifetime Qt Champion
        wrote on 12 Jun 2016, 18:21 last edited by
        #4

        TEMPLATE = lib creates a dynamic shared library (lib+dll) by default. To make a static library (lib) you need to pass CONFIG += staticlib in the .pro of your library.

        K 1 Reply Last reply 12 Jun 2016, 18:45
        2
        • K koahnig
          12 Jun 2016, 18:15

          @Chris-Kawa

          Not exactly.

          More like this here:

          First classes level1 are exprted to dll1

          class DLL1SHARED_EXPORT level1_1
          {
          };
          

          Second classes level2 are exported to dll2

          class DLL2SHARED_EXPORT level2_1 : public level1_1
          {
          };
          

          Finally classes level_main are initially statically linked with code in program main.

          class level_main_1: public level2_1
          {
          };
          

          main.exe has sized of about 1.2 MB as long as the compilation is done with all those "level_main_" classes through a project template "app" and one .pro file.
          Duplication of .pro-file, renaming in one "TEMPLATE = app" -> "TEMPLATE = lib". Also ensured that only the file with "TEMPLATE = app" holds the source file with "program main(...)". LIBS += statement added to point to location of .lib (all the resulting dll).
          The other .pro holds all remaining code files.

          Since I did NOT add so far the macro "DLL_MAIN_SHARED_EXPORT" or something to the definition of classes starting with "level_main_" I did expect that the size of the resulting .exe is statically linked and has a similar size of 1.2 MB.

          However, apparently there is a dll already created and the exe size has dropped to 50 kB of .exe.

          The only explanation I have at the moment is that a dynamic lib is default for "TEMPLATE=LIB" and I did not bother to change to make the library static through qmake. However, I thought that I would need also the macro "DLL_MAIN_SHARED_EXPORT" mimic for actually creating a dll.

          K Offline
          K Offline
          kshegunov
          Moderators
          wrote on 12 Jun 2016, 18:23 last edited by kshegunov 6 Dec 2016, 18:23
          #5

          @koahnig
          Hi,

          As the title already almost says, is it possible to create a dll without explicit dllexport?

          If I remember correctly, if you don't export anything the linker will not generate any code (thus no dll).

          The only explanation I have at the moment is that a dynamic lib is default for "TEMPLATE=LIB"

          It is. If you don't put "CONFIG += static" qmake will generate a makefile that compiles into a dynamic library.

          However, I thought that I would need also the macro "DLL_MAIN_SHARED_EXPORT" mimic for actually creating a dll.

          I don't follow. You don't export from static libraries in the first place. A static library has no notion of visibility, it doesn't have a header or any way to load dependencies. It's only a collection of translation units (object files). So exporting/importing is not relevant to static libraries at all.

          Kind regards.

          Read and abide by the Qt Code of Conduct

          1 Reply Last reply
          2
          • C Chris Kawa
            12 Jun 2016, 18:21

            TEMPLATE = lib creates a dynamic shared library (lib+dll) by default. To make a static library (lib) you need to pass CONFIG += staticlib in the .pro of your library.

            K Offline
            K Offline
            koahnig
            wrote on 12 Jun 2016, 18:45 last edited by
            #6

            @Chris-Kawa said:

            TEMPLATE = lib creates a dynamic shared library (lib+dll) by default. To make a static library (lib) you need to pass CONFIG += staticlib in the .pro of your library.

            @kshegunov

            I can live with that, but why should I handle an additional include file?

            Just created a new lib project called "testDll" and 4 files are created plus .pro.user. Those files are:
            TestDll.cpp

            #include "TestDll.h"
            TestDll::TestDll()
            {
            }
            
            

            TestDll.h

            #ifndef TESTDLL_H
            #define TESTDLL_H
            #include "testdll_global.h"
            class TESTDLLSHARED_EXPORT TestDll
            {
            public:
                TestDll();
            };
            #endif // TESTDLL_H
            

            testdll_global.h

            #ifndef TESTDLL_GLOBAL_H
            #define TESTDLL_GLOBAL_H
            #include <QtCore/qglobal.h>
            #if defined(TESTDLL_LIBRARY)
            #  define TESTDLLSHARED_EXPORT Q_DECL_EXPORT
            #else
            #  define TESTDLLSHARED_EXPORT Q_DECL_IMPORT
            #endif
            #endif // TESTDLL_GLOBAL_H
            

            and the TestDll.pro

            #-------------------------------------------------
            #
            # Project created by QtCreator 2016-06-12T20:32:38
            #
            #-------------------------------------------------
            QT       -= gui
            
            TARGET = testDll
            TEMPLATE = lib
            
            DEFINES += TESTDLL_LIBRARY
            
            SOURCES += TestDll.cpp
            
            HEADERS += TestDll.h\
                    testdll_global.h
            unix {
                target.path = /usr/lib
                INSTALLS += target
            }
            

            My conclusion was that I need to have always the "testdll_global.h" and the macro "TESTDLLSHARED_EXPORT" in every header and every class declared which I like to export to the dll.

            Vote the answer(s) that helped you to solve your issue(s)

            1 Reply Last reply
            0
            • K Offline
              K Offline
              koahnig
              wrote on 12 Jun 2016, 18:50 last edited by
              #7

              To add to previous post:
              The new conclusion would be that one can save quite a bit of work when ignoring the "testdll_global.h" and the macro "TESTDLLSHARED_EXPORT" stuff.
              So why is that stuff added in the project template, if I do not need to have it at least with Qt?

              Vote the answer(s) that helped you to solve your issue(s)

              1 Reply Last reply
              0
              • C Offline
                C Offline
                Chris Kawa
                Lifetime Qt Champion
                wrote on 12 Jun 2016, 18:51 last edited by Chris Kawa 6 Dec 2016, 18:51
                #8

                @koahnig said:

                Just created a new lib project called "testDll" and 4 files are created plus .pro.user.

                Note that the wizard lets you choose the type of the project. The default is "Shared Library" i.e. a DLL. That is what you got and for that the macros are required.

                The other settings in the wizard are "Statically Linked Library" and "Qt Plugin". The statically linked library has only two files - a .h/.cpp of your class without the extra export/import macros.

                K 1 Reply Last reply 12 Jun 2016, 19:01
                0
                • C Chris Kawa
                  12 Jun 2016, 18:51

                  @koahnig said:

                  Just created a new lib project called "testDll" and 4 files are created plus .pro.user.

                  Note that the wizard lets you choose the type of the project. The default is "Shared Library" i.e. a DLL. That is what you got and for that the macros are required.

                  The other settings in the wizard are "Statically Linked Library" and "Qt Plugin". The statically linked library has only two files - a .h/.cpp of your class without the extra export/import macros.

                  K Offline
                  K Offline
                  koahnig
                  wrote on 12 Jun 2016, 19:01 last edited by
                  #9

                  @Chris-Kawa said:

                  @koahnig said:

                  Just created a new lib project called "testDll" and 4 files are created plus .pro.user.

                  Note that the wizard lets you choose the type of the project. The default is "Shared Library" i.e. a DLL. That is what you got and for that the macros are required.

                  The other settings in the wizard are "Statically Linked Library" and "Qt Plugin". The statically linked library has only two files - a .h/.cpp of your class without the extra export/import macros.

                  Agreed and all this is fine, but actually one can create a dll without using "testdll_global.h".

                  Possibly our posts crossed:
                  @koahnig said:

                  To add to previous post:
                  The new conclusion would be that one can save quite a bit of work when ignoring the "testdll_global.h" and the macro "TESTDLLSHARED_EXPORT" stuff.
                  So why is that stuff added in the project template, if I do not need to have it at least with Qt?

                  Basically there is my issue, why shall I add an include not required?

                  It looks logical to have the include "testdll_global.h", because it makes the look compatible to the typical things you have to do for creating a dll. However, as long as you stay within the Qt world it is additional work which is not required?

                  Vote the answer(s) that helped you to solve your issue(s)

                  1 Reply Last reply
                  0
                  • C Offline
                    C Offline
                    Chris Kawa
                    Lifetime Qt Champion
                    wrote on 12 Jun 2016, 19:26 last edited by
                    #10

                    @koahnig said:

                    However, as long as you stay within the Qt world it is additional work which is not required?

                    It has nothing to do with Qt.
                    For a dynamically linked library you do need the import/export stuff, at least if you want to behave nicely. If you try it with MSVC you will see that your symbols are not visible if you don't export them.

                    The thing you experience is a weirdness of GCC (or MinGW in this case). It has this weird behavior that if you don't export anything explicitly it will export everything (sic!). I'm guessing it's to keep libraries that didn't have MSVC in mind working. As soon as you export any symbol the MSVC-like behavior kicks in and only those symbols declared as export will be exported.

                    To test that try to build your lib without any symbols exported (comment out the macros). Use DependencyWalker to examine the library - note that everytihing is exported. Now add this single export in your header: ___declspec( dllexport ) int foo; and inspect the library again - only foo is exported.

                    K K 2 Replies Last reply 12 Jun 2016, 19:34
                    2
                    • C Chris Kawa
                      12 Jun 2016, 19:26

                      @koahnig said:

                      However, as long as you stay within the Qt world it is additional work which is not required?

                      It has nothing to do with Qt.
                      For a dynamically linked library you do need the import/export stuff, at least if you want to behave nicely. If you try it with MSVC you will see that your symbols are not visible if you don't export them.

                      The thing you experience is a weirdness of GCC (or MinGW in this case). It has this weird behavior that if you don't export anything explicitly it will export everything (sic!). I'm guessing it's to keep libraries that didn't have MSVC in mind working. As soon as you export any symbol the MSVC-like behavior kicks in and only those symbols declared as export will be exported.

                      To test that try to build your lib without any symbols exported (comment out the macros). Use DependencyWalker to examine the library - note that everytihing is exported. Now add this single export in your header: ___declspec( dllexport ) int foo; and inspect the library again - only foo is exported.

                      K Offline
                      K Offline
                      koahnig
                      wrote on 12 Jun 2016, 19:34 last edited by
                      #11

                      @Chris-Kawa said:

                      The thing you experience is a weirdness of GCC (or MinGW in this case). It has this weird behavior that if you don't export anything explicitly it will export everything (sic!). I'm guessing it's to keep libraries that didn't have MSVC in mind working. As soon as you export any symbol the MSVC-like behavior kicks in and only those symbols declared as export will be exported.

                      OK, that is the explanation I was looking for.
                      I thought already right from the beginning that this might have something to do with MinGW. However, assuming such weirdness right away is typically not a good choice. Similar to assuming it is a compiler error if you do not find something right away.

                      Thanks a lot for confirmation. I was trying to find a note somewhere, but I could not.

                      Vote the answer(s) that helped you to solve your issue(s)

                      1 Reply Last reply
                      0
                      • C Chris Kawa
                        12 Jun 2016, 19:26

                        @koahnig said:

                        However, as long as you stay within the Qt world it is additional work which is not required?

                        It has nothing to do with Qt.
                        For a dynamically linked library you do need the import/export stuff, at least if you want to behave nicely. If you try it with MSVC you will see that your symbols are not visible if you don't export them.

                        The thing you experience is a weirdness of GCC (or MinGW in this case). It has this weird behavior that if you don't export anything explicitly it will export everything (sic!). I'm guessing it's to keep libraries that didn't have MSVC in mind working. As soon as you export any symbol the MSVC-like behavior kicks in and only those symbols declared as export will be exported.

                        To test that try to build your lib without any symbols exported (comment out the macros). Use DependencyWalker to examine the library - note that everytihing is exported. Now add this single export in your header: ___declspec( dllexport ) int foo; and inspect the library again - only foo is exported.

                        K Offline
                        K Offline
                        kshegunov
                        Moderators
                        wrote on 12 Jun 2016, 19:36 last edited by
                        #12

                        @Chris-Kawa

                        It has nothing to do with Qt.

                        Nor with C++ actually. These things are OS specific and depend on the implementation of the linker/loader and the ABI.

                        I'm guessing it's to keep libraries that didn't have MSVC in mind working.

                        Most probably, yes. This is the default behavior on Linux - everything is exported by default, so I would assume this is to "facilitate" porting from *nix to windows.

                        @koahnig

                        Basically there is my issue, why shall I add an include not required?

                        As Chris said, it might not be an include file, but you do need the linkage specifiers.

                        Read and abide by the Qt Code of Conduct

                        K 1 Reply Last reply 12 Jun 2016, 19:51
                        1
                        • K kshegunov
                          12 Jun 2016, 19:36

                          @Chris-Kawa

                          It has nothing to do with Qt.

                          Nor with C++ actually. These things are OS specific and depend on the implementation of the linker/loader and the ABI.

                          I'm guessing it's to keep libraries that didn't have MSVC in mind working.

                          Most probably, yes. This is the default behavior on Linux - everything is exported by default, so I would assume this is to "facilitate" porting from *nix to windows.

                          @koahnig

                          Basically there is my issue, why shall I add an include not required?

                          As Chris said, it might not be an include file, but you do need the linkage specifiers.

                          K Offline
                          K Offline
                          koahnig
                          wrote on 12 Jun 2016, 19:51 last edited by
                          #13

                          @kshegunov

                          That makes sense.

                          I have added the import/export stuff in the mean time. So basically all is broadened to hopefully all compilers and OSs. ;)

                          Vote the answer(s) that helped you to solve your issue(s)

                          K 1 Reply Last reply 12 Jun 2016, 19:57
                          0
                          • K koahnig
                            12 Jun 2016, 19:51

                            @kshegunov

                            That makes sense.

                            I have added the import/export stuff in the mean time. So basically all is broadened to hopefully all compilers and OSs. ;)

                            K Offline
                            K Offline
                            kshegunov
                            Moderators
                            wrote on 12 Jun 2016, 19:57 last edited by kshegunov
                            #14

                            @koahnig

                            So basically all is broadened to hopefully all compilers and OSs.

                            It should be. To be honest, this default exporting behavior is one of the more suspicious decisions in Linux. Windows' way of enforcing symbols to be hidden by default (like we have with classes' members) is much more logical. I actually define two macros when making shared libraries - one that is for the export/import and one that forces symbols not explicitly exported to be hidden on Linux, thus getting a similar binary interface on all platforms; like done here.

                            Kind regards.

                            Read and abide by the Qt Code of Conduct

                            1 Reply Last reply
                            0

                            11/14

                            12 Jun 2016, 19:34

                            • Login

                            • Login or register to search.
                            11 out of 14
                            • First post
                              11/14
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved