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. dll using static const char*
QtWS25 Last Chance

dll using static const char*

Scheduled Pinned Locked Moved Solved C++ Gurus
dllstatic const
19 Posts 2 Posters 9.3k 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 Offline
    K Offline
    koahnig
    wrote on last edited by
    #1

    I am changing a library with

    static const char* m_Blabla = "BloBli";
    

    to a dll. Now when linking those statements cause a linker error. I have found already a possible solution with a shared data segment. I am not sure if this is good way to move forward.

    Since strings are really const and never change, it is save to use this across different applications.
    Also possible recompilation under linux may be handled with some macro definition.

    However, are there other better options?
    And what are the draw backs?

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

    kshegunovK 1 Reply Last reply
    0
    • K koahnig

      I am changing a library with

      static const char* m_Blabla = "BloBli";
      

      to a dll. Now when linking those statements cause a linker error. I have found already a possible solution with a shared data segment. I am not sure if this is good way to move forward.

      Since strings are really const and never change, it is save to use this across different applications.
      Also possible recompilation under linux may be handled with some macro definition.

      However, are there other better options?
      And what are the draw backs?

      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by kshegunov
      #2

      @koahnig

      Hi!

      Now when linking those statements cause a linker error.

      What are you getting? Undefined reference?

      It should work without much problem, at least to my experience, i.e.:
      header file

      Q_DECL_EXPORT extern const char * m_Blabla;
      

      then in source:

      const char * m_Blabla = "BloBli";
      

      Two points here:

      1. Q_DECL_EXPORT, should be import when linking into the user code (you know the drill) :D
      2. I really advise to enforce the pointer not moving as well as the characters not being mutable, that is const char * const

      I have found already a possible solution with a shared data segment.

      Why do you need that?

      And what are the draw backs?

      There's one very specific thing with static variables on Windows. You can get two instances of the same variable if you link with both the release and debug version of the same library (this doesn't happen on *nix).

      Kind regards.

      Read and abide by the Qt Code of Conduct

      K 1 Reply Last reply
      2
      • kshegunovK kshegunov

        @koahnig

        Hi!

        Now when linking those statements cause a linker error.

        What are you getting? Undefined reference?

        It should work without much problem, at least to my experience, i.e.:
        header file

        Q_DECL_EXPORT extern const char * m_Blabla;
        

        then in source:

        const char * m_Blabla = "BloBli";
        

        Two points here:

        1. Q_DECL_EXPORT, should be import when linking into the user code (you know the drill) :D
        2. I really advise to enforce the pointer not moving as well as the characters not being mutable, that is const char * const

        I have found already a possible solution with a shared data segment.

        Why do you need that?

        And what are the draw backs?

        There's one very specific thing with static variables on Windows. You can get two instances of the same variable if you link with both the release and debug version of the same library (this doesn't happen on *nix).

        Kind regards.

        K Offline
        K Offline
        koahnig
        wrote on last edited by
        #3

        @kshegunov

        Thanks for reply and sorry I was not really precise
        Here is the error message

        warning: 'KlaSlim::__ION_NONE' redeclared without dllimport attribute: previous dllimport ignored [-Wattributes]
        error: definition of static data member 'KlaSlim::__ION_NONE' of dllimport'd class
        

        and I am using static member data as you see from the error message.

        At the moment I am lost why I have the warning. I have basically several dlls but the declaration is with the dll having all the others as basis.

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

        kshegunovK 1 Reply Last reply
        0
        • K koahnig

          @kshegunov

          Thanks for reply and sorry I was not really precise
          Here is the error message

          warning: 'KlaSlim::__ION_NONE' redeclared without dllimport attribute: previous dllimport ignored [-Wattributes]
          error: definition of static data member 'KlaSlim::__ION_NONE' of dllimport'd class
          

          and I am using static member data as you see from the error message.

          At the moment I am lost why I have the warning. I have basically several dlls but the declaration is with the dll having all the others as basis.

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by
          #4

          @koahnig said:

          I am using static member data as you see from the error message.

          Oh! I thought you meant a global one. Okay this talks to me somewhat. :)

          static const char* m_Blabla = "BloBli";
          

          Do you have this in the header in the class' declaration?

          If so, just split it up between the header and the source, e.g.

          class EXPORT_MACRO MyClass
          {
          public:
              static const char * const myStaticVar;
          }
          

          and then in the source:

          const char * const MyClass::myStaticVar = "Some string";
          

          I think this should fix it ;)

          Read and abide by the Qt Code of Conduct

          K 1 Reply Last reply
          0
          • kshegunovK kshegunov

            @koahnig said:

            I am using static member data as you see from the error message.

            Oh! I thought you meant a global one. Okay this talks to me somewhat. :)

            static const char* m_Blabla = "BloBli";
            

            Do you have this in the header in the class' declaration?

            If so, just split it up between the header and the source, e.g.

            class EXPORT_MACRO MyClass
            {
            public:
                static const char * const myStaticVar;
            }
            

            and then in the source:

            const char * const MyClass::myStaticVar = "Some string";
            

            I think this should fix it ;)

            K Offline
            K Offline
            koahnig
            wrote on last edited by
            #5

            @kshegunov

            Basically that is the way I did the definition and initialization.

            Changed now from

            class EXPORT_MACRO MyClass
            {
            public:
                static const char * myStaticVar;
            }
            

            to

            class EXPORT_MACRO MyClass
            {
            public:
                static const char * const myStaticVar;
            }
            

            Using Q_DECL_IMPORT and Q_DECL_EXPORT as it should be done.

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

            kshegunovK 1 Reply Last reply
            0
            • K koahnig

              @kshegunov

              Basically that is the way I did the definition and initialization.

              Changed now from

              class EXPORT_MACRO MyClass
              {
              public:
                  static const char * myStaticVar;
              }
              

              to

              class EXPORT_MACRO MyClass
              {
              public:
                  static const char * const myStaticVar;
              }
              

              Using Q_DECL_IMPORT and Q_DECL_EXPORT as it should be done.

              kshegunovK Offline
              kshegunovK Offline
              kshegunov
              Moderators
              wrote on last edited by
              #6

              @koahnig
              I'm sorry, I don't follow; does the suggested change fix the problem, or you had already done it like that? Do you still experience the linking problem?

              Read and abide by the Qt Code of Conduct

              K 1 Reply Last reply
              0
              • kshegunovK kshegunov

                @koahnig
                I'm sorry, I don't follow; does the suggested change fix the problem, or you had already done it like that? Do you still experience the linking problem?

                K Offline
                K Offline
                koahnig
                wrote on last edited by
                #7

                @kshegunov
                Sorry, too deep in thoughts.

                No, it does not fix the problem.

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

                kshegunovK 1 Reply Last reply
                0
                • K koahnig

                  @kshegunov
                  Sorry, too deep in thoughts.

                  No, it does not fix the problem.

                  kshegunovK Offline
                  kshegunovK Offline
                  kshegunov
                  Moderators
                  wrote on last edited by kshegunov
                  #8

                  @koahnig
                  Hello,
                  The plot thickens. I think (don't hold me to it, as I haven't been actively developing on Win for years) the static variable should be visible ... can you get a symbol dump from the dll and see if it was properly exported?
                  As a side note you could also try with a global variable (not scoped in a class, as in my first post) just to check everything is okay with that at least?

                  Kind regards.

                  Read and abide by the Qt Code of Conduct

                  K 1 Reply Last reply
                  0
                  • kshegunovK kshegunov

                    @koahnig
                    Hello,
                    The plot thickens. I think (don't hold me to it, as I haven't been actively developing on Win for years) the static variable should be visible ... can you get a symbol dump from the dll and see if it was properly exported?
                    As a side note you could also try with a global variable (not scoped in a class, as in my first post) just to check everything is okay with that at least?

                    Kind regards.

                    K Offline
                    K Offline
                    koahnig
                    wrote on last edited by
                    #9

                    @kshegunov

                    the symbol dump of dependency walker lists the entry. So it should be exported.
                    The error comes with the initialization. I got a whole list. If I am marking the one listed, the next one will pop up as the source of error.

                    I am gong to try the global version of your first suggestion. If it works, I am not loosing anything.

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

                    kshegunovK 1 Reply Last reply
                    0
                    • K koahnig

                      @kshegunov

                      the symbol dump of dependency walker lists the entry. So it should be exported.
                      The error comes with the initialization. I got a whole list. If I am marking the one listed, the next one will pop up as the source of error.

                      I am gong to try the global version of your first suggestion. If it works, I am not loosing anything.

                      kshegunovK Offline
                      kshegunovK Offline
                      kshegunov
                      Moderators
                      wrote on last edited by
                      #10

                      @koahnig said:

                      The error comes with the initialization.

                      What initialization? There's no initialization that's connected to linking to my knowledge. And for linking to occur the symbol must only be found by it's fully qualified (and decorated) name, nothing more.

                      Read and abide by the Qt Code of Conduct

                      K 1 Reply Last reply
                      0
                      • kshegunovK kshegunov

                        @koahnig said:

                        The error comes with the initialization.

                        What initialization? There's no initialization that's connected to linking to my knowledge. And for linking to occur the symbol must only be found by it's fully qualified (and decorated) name, nothing more.

                        K Offline
                        K Offline
                        koahnig
                        wrote on last edited by
                        #11

                        @kshegunov
                        with this statement

                        const char * const MyClass::myStaticVar = "Some string";
                        

                        I have a list of these member initializations. When I comment out the first one, the next becomes the problem.
                        However, dependency walker shows the entry with and without the member initializations.

                        Not sure yet, if there is somewhere an include without import and export macro. It is a bit strange.

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

                        kshegunovK 1 Reply Last reply
                        0
                        • K koahnig

                          @kshegunov
                          with this statement

                          const char * const MyClass::myStaticVar = "Some string";
                          

                          I have a list of these member initializations. When I comment out the first one, the next becomes the problem.
                          However, dependency walker shows the entry with and without the member initializations.

                          Not sure yet, if there is somewhere an include without import and export macro. It is a bit strange.

                          kshegunovK Offline
                          kshegunovK Offline
                          kshegunov
                          Moderators
                          wrote on last edited by kshegunov
                          #12

                          @koahnig
                          Okay, wait a minute!
                          You can't have a binary generated if the linker doesn't run properly. So this:

                          const char * const MyClass::myStaticVar = "Some string";
                          

                          causing a linker error would mean your dll is not linked, how does dependency walker report symbols then? Have I missed something here? Do you mind putting the exact lines from the header (with wrapper class name, inheritance etc) and source for one of your static variables? And also please show the portion of your .pro dealing with linkage, preprocessor macros and how you define the export macro itself. This would really help things along.

                          Read and abide by the Qt Code of Conduct

                          K 2 Replies Last reply
                          1
                          • kshegunovK kshegunov

                            @koahnig
                            Okay, wait a minute!
                            You can't have a binary generated if the linker doesn't run properly. So this:

                            const char * const MyClass::myStaticVar = "Some string";
                            

                            causing a linker error would mean your dll is not linked, how does dependency walker report symbols then? Have I missed something here? Do you mind putting the exact lines from the header (with wrapper class name, inheritance etc) and source for one of your static variables? And also please show the portion of your .pro dealing with linkage, preprocessor macros and how you define the export macro itself. This would really help things along.

                            K Offline
                            K Offline
                            koahnig
                            wrote on last edited by
                            #13

                            @kshegunov

                            I should better make a condensed case of it then. You are right, possibly I messed up things somewhere there. I thought I lined it up properly.

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

                            1 Reply Last reply
                            0
                            • kshegunovK kshegunov

                              @koahnig
                              Okay, wait a minute!
                              You can't have a binary generated if the linker doesn't run properly. So this:

                              const char * const MyClass::myStaticVar = "Some string";
                              

                              causing a linker error would mean your dll is not linked, how does dependency walker report symbols then? Have I missed something here? Do you mind putting the exact lines from the header (with wrapper class name, inheritance etc) and source for one of your static variables? And also please show the portion of your .pro dealing with linkage, preprocessor macros and how you define the export macro itself. This would really help things along.

                              K Offline
                              K Offline
                              koahnig
                              wrote on last edited by
                              #14

                              @kshegunov said:

                              Okay, wait a minute!
                              You can't have a binary generated if the linker doesn't run properly. So this:

                              const char * const MyClass::myStaticVar = "Some string";
                              causing a linker error would mean your dll is not linked, how does dependency walker report symbols then?
                              I have used the dependency walker with dll. You are right since the link step does give an error I am getting no exe.

                              I have tried to get a reduced version showing the problem. But the reduced version can compile and link and run. Therefore, I have to check my complex setup for a flaw. When starting the discussion I thought I am trying to do something which is not possible at all.

                              Many thanks for your sparring support, it is appreciated.

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

                              kshegunovK 1 Reply Last reply
                              0
                              • K koahnig

                                @kshegunov said:

                                Okay, wait a minute!
                                You can't have a binary generated if the linker doesn't run properly. So this:

                                const char * const MyClass::myStaticVar = "Some string";
                                causing a linker error would mean your dll is not linked, how does dependency walker report symbols then?
                                I have used the dependency walker with dll. You are right since the link step does give an error I am getting no exe.

                                I have tried to get a reduced version showing the problem. But the reduced version can compile and link and run. Therefore, I have to check my complex setup for a flaw. When starting the discussion I thought I am trying to do something which is not possible at all.

                                Many thanks for your sparring support, it is appreciated.

                                kshegunovK Offline
                                kshegunovK Offline
                                kshegunov
                                Moderators
                                wrote on last edited by
                                #15

                                @koahnig said:

                                I have used the dependency walker with dll. You are right since the link step does give an error I am getting no exe.

                                But then, the initialization wouldn't be in the exe would it? .. as the variable is declared in the dll (and the dll source shouldn't be at all involved with said exe). :)

                                When starting the discussion I thought I am trying to do something which is not possible at all.

                                Not at all, it's quite commonly done, albeit I prefer in most cases to have a function that returns the relevant object/variable (not really applicable in your case, though).

                                Many thanks for your sparring support, it is appreciated.

                                No problem! I enjoy a good mystery. ;)
                                Cheers!

                                Read and abide by the Qt Code of Conduct

                                K 1 Reply Last reply
                                0
                                • kshegunovK kshegunov

                                  @koahnig said:

                                  I have used the dependency walker with dll. You are right since the link step does give an error I am getting no exe.

                                  But then, the initialization wouldn't be in the exe would it? .. as the variable is declared in the dll (and the dll source shouldn't be at all involved with said exe). :)

                                  When starting the discussion I thought I am trying to do something which is not possible at all.

                                  Not at all, it's quite commonly done, albeit I prefer in most cases to have a function that returns the relevant object/variable (not really applicable in your case, though).

                                  Many thanks for your sparring support, it is appreciated.

                                  No problem! I enjoy a good mystery. ;)
                                  Cheers!

                                  K Offline
                                  K Offline
                                  koahnig
                                  wrote on last edited by
                                  #16

                                  @kshegunov said:

                                  But then, the initialization wouldn't be in the exe would it? .. as the variable is declared in the dll (and the dll source shouldn't be at all involved with said exe). :)

                                  No. The whole code of class and therefore its member initialization shall be part of a dll. That is the reason why I was checking the particular dll.

                                  However, within the linkage of the exe suddenly the problem pops up.

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

                                  kshegunovK 1 Reply Last reply
                                  0
                                  • K koahnig

                                    @kshegunov said:

                                    But then, the initialization wouldn't be in the exe would it? .. as the variable is declared in the dll (and the dll source shouldn't be at all involved with said exe). :)

                                    No. The whole code of class and therefore its member initialization shall be part of a dll. That is the reason why I was checking the particular dll.

                                    However, within the linkage of the exe suddenly the problem pops up.

                                    kshegunovK Offline
                                    kshegunovK Offline
                                    kshegunov
                                    Moderators
                                    wrote on last edited by
                                    #17

                                    @koahnig said:

                                    No. The whole code of class and therefore its member initialization shall be part of a dll. That is the reason why I was checking the particular dll.

                                    This means you just can't get a linker error in the line where the var is initialized, or you won't get a dll.
                                    As for the exe that links the dll it should be oblivious to the statics initialization and I see no way how code that's internal to dll could cause a linking error in the exe. What I mean is this:

                                    1. dll header:
                                    class EXPORT_MACRO MyClass
                                    {
                                    public:
                                        static const char * const myStaticVar;
                                    }
                                    
                                    1. dll source
                                    const char * const MyClass::myStaticVar = "Some string";
                                    

                                    So the exe can't actually see MyClass::myStaticVar's initialization (code snippet 2); it can't have anything to do with that. This is a static initialization that's done by the loader immediately after the dll is mapped in memory. The executable has no bearing or any control over it. I hope I explained it well enough.

                                    Kind regards.

                                    Read and abide by the Qt Code of Conduct

                                    K 1 Reply Last reply
                                    0
                                    • kshegunovK kshegunov

                                      @koahnig said:

                                      No. The whole code of class and therefore its member initialization shall be part of a dll. That is the reason why I was checking the particular dll.

                                      This means you just can't get a linker error in the line where the var is initialized, or you won't get a dll.
                                      As for the exe that links the dll it should be oblivious to the statics initialization and I see no way how code that's internal to dll could cause a linking error in the exe. What I mean is this:

                                      1. dll header:
                                      class EXPORT_MACRO MyClass
                                      {
                                      public:
                                          static const char * const myStaticVar;
                                      }
                                      
                                      1. dll source
                                      const char * const MyClass::myStaticVar = "Some string";
                                      

                                      So the exe can't actually see MyClass::myStaticVar's initialization (code snippet 2); it can't have anything to do with that. This is a static initialization that's done by the loader immediately after the dll is mapped in memory. The executable has no bearing or any control over it. I hope I explained it well enough.

                                      Kind regards.

                                      K Offline
                                      K Offline
                                      koahnig
                                      wrote on last edited by
                                      #18

                                      @kshegunov

                                      Thanks for your patience and continued support.

                                      I have found the problem. It was caused right between keyboard and chair ;)

                                      As shown in one of my early responses the error respectively the warning, which was in this case more important.

                                      @koahnig said:

                                      Here is the error message

                                      warning: 'KlaSlim::__ION_NONE' redeclared without dllimport attribute: previous dllimport ignored [-Wattributes]
                                      error: definition of static data member 'KlaSlim::__ION_NONE' of dllimport'd class
                                      

                                      What puzzled me was the reference redeclared without dllimport. I have the typical mechanism as suggested by Qt dll template for export and import. I have added another wrap around it making it usuable also when I do not like to have a dll at all.

                                      After your feedback indicated what I am doing is the right way, I had focused on why is the stuff redeclared without dllimport. However, I could not a problem here. Actually all is fine there with the includes and they have always the import or the export declaration. Unfortunately implementation files slipped into the compilation of the application.

                                      The warning text is misleading though, but it was actually showing the cause, duplicated declarations or better duplicated implementations.

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

                                      kshegunovK 1 Reply Last reply
                                      0
                                      • K koahnig

                                        @kshegunov

                                        Thanks for your patience and continued support.

                                        I have found the problem. It was caused right between keyboard and chair ;)

                                        As shown in one of my early responses the error respectively the warning, which was in this case more important.

                                        @koahnig said:

                                        Here is the error message

                                        warning: 'KlaSlim::__ION_NONE' redeclared without dllimport attribute: previous dllimport ignored [-Wattributes]
                                        error: definition of static data member 'KlaSlim::__ION_NONE' of dllimport'd class
                                        

                                        What puzzled me was the reference redeclared without dllimport. I have the typical mechanism as suggested by Qt dll template for export and import. I have added another wrap around it making it usuable also when I do not like to have a dll at all.

                                        After your feedback indicated what I am doing is the right way, I had focused on why is the stuff redeclared without dllimport. However, I could not a problem here. Actually all is fine there with the includes and they have always the import or the export declaration. Unfortunately implementation files slipped into the compilation of the application.

                                        The warning text is misleading though, but it was actually showing the cause, duplicated declarations or better duplicated implementations.

                                        kshegunovK Offline
                                        kshegunovK Offline
                                        kshegunov
                                        Moderators
                                        wrote on last edited by kshegunov
                                        #19

                                        @koahnig said:

                                        Thanks for your patience and continued support. I have found the problem.

                                        That's great. I'm glad I was able to contribute. :)

                                        Unfortunately implementation files slipped into the compilation of the application.

                                        Ah, sneaky .cpps :)

                                        The warning text is misleading though, but it was actually showing the cause, duplicated declarations or better duplicated implementations.

                                        Sadly that's always the case with the linker. A linker is dumb as a shoe, it doesn't have any context or semantics to the code, it just reorders symbols and puts addresses, that's why linker error are so cryptic. :)

                                        I myself get into a hateful depression when I get the notorious "undefined vtable for ..." :D

                                        In any case, I'm glad it worked out.
                                        Cheers!

                                        Read and abide by the Qt Code of Conduct

                                        1 Reply Last reply
                                        1

                                        • Login

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