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?

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.8k 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.
  • 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

                      14/14

                      12 Jun 2016, 19:57

                      • Login

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