Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Unresolved external symbol in a DLL

Unresolved external symbol in a DLL

Scheduled Pinned Locked Moved C / C++ / MFC
c++helpquestion
23 Posts 4 Posters 0 Views 1 Watching
  • 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.
  • G George_George

    Hello everyone, I am developing a DLL and making another console application to link with the DLL. The DLL expose type CFoo, create an instance and the application consumes it. There is error like this. The source code of DLL and main are listed below, any ideas?

    1>main.obj : error LNK2001: unresolved external symbol "class CFoo foo" (?foo@@3VCFoo@@A)

    foo.h (defines exposed type in the DLL)
    class __declspec (dllexport) CFoo
    {
    public:

    CFoo();
    
    int foo1();
    
    int foo2();
    

    };

    dllmain.cpp (defines type implementation inside dll)

    #include "foo.h"

    CFoo::CFoo()
    {
    return;
    }

    int CFoo::foo1()
    {
    return 100;
    }

    int CFoo::foo2()
    {
    return 200;
    }

    CFoo foo;

    main.cpp (the console application which dynamically links with the DLL using import library)

    #include "foo.h"

    extern CFoo foo;

    int main()
    {
    int i = foo.foo1();
    i = foo.foo2();

    return 0;
    

    }

    thanks in advance, George

    N Offline
    N Offline
    Naveen
    wrote on last edited by
    #3

    George_George wrote:

    CFoo foo;

    This is not enough, you have to export the foo variable, like __declspec (dllexport) CFoo foo;

    George_George wrote:

    extern CFoo foo;

    Also in the exe, you have to import the variable __declspec (dllimport) CFoo foo;

    nave [OpenedFileFinder] [My Blog]

    G 1 Reply Last reply
    0
    • N nbugalia

      George_George wrote:

      extern CFoo foo;

      Replace the above by -

      CFoo foo2;

      G Offline
      G Offline
      George_George
      wrote on last edited by
      #4

      I am confused, nbugalia! In my design, I want to create object instance in DLL and access the object instance from the hosting executable from extern reference. Your code change impacts my design... :-) Any comments? regards, George

      N 1 Reply Last reply
      0
      • N Naveen

        George_George wrote:

        CFoo foo;

        This is not enough, you have to export the foo variable, like __declspec (dllexport) CFoo foo;

        George_George wrote:

        extern CFoo foo;

        Also in the exe, you have to import the variable __declspec (dllimport) CFoo foo;

        nave [OpenedFileFinder] [My Blog]

        G Offline
        G Offline
        George_George
        wrote on last edited by
        #5

        Thanks nave, I have tested your solution works. My question is, if I create a global variable inside a DLL, then in the hosting executable, could I use extern to refer to the variable and use it? regards, George

        N 1 Reply Last reply
        0
        • G George_George

          I am confused, nbugalia! In my design, I want to create object instance in DLL and access the object instance from the hosting executable from extern reference. Your code change impacts my design... :-) Any comments? regards, George

          N Offline
          N Offline
          nbugalia
          wrote on last edited by
          #6

          Here is the Dll file code - foo.h

          class __declspec (dllexport) CFoo
          {
          public:
          CFoo();
          int foo1();
          int foo2();
          };

          **__declspec (dllexport) CFoo foo;re>

          Foo.cpp

          #include "Foo.h"

          CFoo::CFoo()
          {
          return;
          }
          int CFoo::foo1()
          {
          return 100;
          }
          int CFoo::foo2()
          {
          return 200;
          }

          and here is the console based application code -
          Foo.h

          class __declspec (dllimport) CFoo
          {
          public:
          CFoo();
          int foo1();
          int foo2();
          };

          __declspec (dllimport) CFoo foo;

          test.cpp
          #include "foo.h"
          int main()
          {
          int i = foo.foo1();
          i = foo.foo2();
          return 0;
          }

          Don't forget to set the dependency to Foo.lib file in the test project settings.
          Hope this will help. :-D**

          G 1 Reply Last reply
          0
          • G George_George

            Thanks nave, I have tested your solution works. My question is, if I create a global variable inside a DLL, then in the hosting executable, could I use extern to refer to the variable and use it? regards, George

            N Offline
            N Offline
            Naveen
            wrote on last edited by
            #7

            George_George wrote:

            could I use extern to refer to the variable and use it?

            No. you should export it to use the variable in the hosting executable..

            nave [OpenedFileFinder] [My Blog]

            G 1 Reply Last reply
            0
            • N nbugalia

              Here is the Dll file code - foo.h

              class __declspec (dllexport) CFoo
              {
              public:
              CFoo();
              int foo1();
              int foo2();
              };

              **__declspec (dllexport) CFoo foo;re>

              Foo.cpp

              #include "Foo.h"

              CFoo::CFoo()
              {
              return;
              }
              int CFoo::foo1()
              {
              return 100;
              }
              int CFoo::foo2()
              {
              return 200;
              }

              and here is the console based application code -
              Foo.h

              class __declspec (dllimport) CFoo
              {
              public:
              CFoo();
              int foo1();
              int foo2();
              };

              __declspec (dllimport) CFoo foo;

              test.cpp
              #include "foo.h"
              int main()
              {
              int i = foo.foo1();
              i = foo.foo2();
              return 0;
              }

              Don't forget to set the dependency to Foo.lib file in the test project settings.
              Hope this will help. :-D**

              G Offline
              G Offline
              George_George
              wrote on last edited by
              #8

              Cool, nbugalia! I want to confirm with you that we could expose, function/class/global variable from a DLL, correct? regards, George

              1 Reply Last reply
              0
              • N Naveen

                George_George wrote:

                could I use extern to refer to the variable and use it?

                No. you should export it to use the variable in the hosting executable..

                nave [OpenedFileFinder] [My Blog]

                G Offline
                G Offline
                George_George
                wrote on last edited by
                #9

                Thanks nave, So, from learning from you, it is legal to expose both function/global variable/class from a DLL? (previously, I think only expose function is allowed.) regards, George

                N 1 Reply Last reply
                0
                • G George_George

                  Thanks nave, So, from learning from you, it is legal to expose both function/global variable/class from a DLL? (previously, I think only expose function is allowed.) regards, George

                  N Offline
                  N Offline
                  Naveen
                  wrote on last edited by
                  #10

                  George_George wrote:

                  So, from learning from you, it is legal to expose both function/global variable/class from a DLL?

                  Yes its legal to expose both functions and variables.

                  nave [OpenedFileFinder] [My Blog]

                  G 1 Reply Last reply
                  0
                  • N Naveen

                    George_George wrote:

                    So, from learning from you, it is legal to expose both function/global variable/class from a DLL?

                    Yes its legal to expose both functions and variables.

                    nave [OpenedFileFinder] [My Blog]

                    G Offline
                    G Offline
                    George_George
                    wrote on last edited by
                    #11

                    Thanks nave, And also legal for exposing class? regards, George

                    N 1 Reply Last reply
                    0
                    • G George_George

                      Thanks nave, And also legal for exposing class? regards, George

                      N Offline
                      N Offline
                      Naveen
                      wrote on last edited by
                      #12

                      Of course classes also :cool:

                      nave [OpenedFileFinder] [My Blog]

                      G 1 Reply Last reply
                      0
                      • G George_George

                        Hello everyone, I am developing a DLL and making another console application to link with the DLL. The DLL expose type CFoo, create an instance and the application consumes it. There is error like this. The source code of DLL and main are listed below, any ideas?

                        1>main.obj : error LNK2001: unresolved external symbol "class CFoo foo" (?foo@@3VCFoo@@A)

                        foo.h (defines exposed type in the DLL)
                        class __declspec (dllexport) CFoo
                        {
                        public:

                        CFoo();
                        
                        int foo1();
                        
                        int foo2();
                        

                        };

                        dllmain.cpp (defines type implementation inside dll)

                        #include "foo.h"

                        CFoo::CFoo()
                        {
                        return;
                        }

                        int CFoo::foo1()
                        {
                        return 100;
                        }

                        int CFoo::foo2()
                        {
                        return 200;
                        }

                        CFoo foo;

                        main.cpp (the console application which dynamically links with the DLL using import library)

                        #include "foo.h"

                        extern CFoo foo;

                        int main()
                        {
                        int i = foo.foo1();
                        i = foo.foo2();

                        return 0;
                        

                        }

                        thanks in advance, George

                        S Offline
                        S Offline
                        Stuart Dootson
                        wrote on last edited by
                        #13

                        You've got two issues:

                        1. In main.cpp, you want to declare CFoo as __declspec(dllimport). The way I do that is to put something like this in foo.h: #if !defined(FOO_DLL) #define FOO_EXP __declspec(dllimport) #else #define FOO_EXP __declspec(dllexport) #endif class FOO_EXP CFoo { ... }; You would define FOO_DLL when building the DLL using, for example, #define FOO_DLL in every source file in the DLL before #including foo.h. You need do nothing in main.cpp>/code>, as that's what the default case caters for.
                        2. As other replies have said, you would need to export CFoo foo; from the DLL.
                        G 1 Reply Last reply
                        0
                        • N Naveen

                          Of course classes also :cool:

                          nave [OpenedFileFinder] [My Blog]

                          G Offline
                          G Offline
                          George_George
                          wrote on last edited by
                          #14

                          Thanks Naveen! I have proved we could expose both class and global variable by DLL and using your mentioned elegant way. :-) But I am not 100% confident. Here is my code, could you have a code review please? DLL Part:

                          // foo.h

                          #ifdef _DLLPROJ_
                          #define DLLEXP __declspec (dllexport)
                          #else
                          #define DLLEXP __declspec (dllimport)
                          #endif

                          DLLEXP class CFoo
                          {
                          public:

                          DLLEXP int foo1();
                          
                          DLLEXP int foo2();
                          

                          };

                          DLLEXP class CFooImpl : CFoo
                          {
                          public:

                          DLLEXP CFooImpl();
                          
                          DLLEXP int foo1();
                          
                          DLLEXP int foo2();
                          

                          };

                          // dllmain.cpp

                          #include "foo.h"

                          CFooImpl::CFooImpl()
                          {
                          return;
                          }

                          int CFooImpl::foo1()
                          {
                          return 100;
                          }

                          int CFooImpl::foo2()
                          {
                          return 200;
                          }

                          DLLEXP CFooImpl foo;

                          Hosting client part

                          // main.cpp

                          #include "foo.h"

                          DLLEXP CFooImpl foo;

                          int main()
                          {
                          CFooImpl foo1;

                          int i = foo.foo1();
                          i = foo.foo2();
                          
                          return 0;
                          

                          }

                          regards, George

                          N S 2 Replies Last reply
                          0
                          • S Stuart Dootson

                            You've got two issues:

                            1. In main.cpp, you want to declare CFoo as __declspec(dllimport). The way I do that is to put something like this in foo.h: #if !defined(FOO_DLL) #define FOO_EXP __declspec(dllimport) #else #define FOO_EXP __declspec(dllexport) #endif class FOO_EXP CFoo { ... }; You would define FOO_DLL when building the DLL using, for example, #define FOO_DLL in every source file in the DLL before #including foo.h. You need do nothing in main.cpp>/code>, as that's what the default case caters for.
                            2. As other replies have said, you would need to export CFoo foo; from the DLL.
                            G Offline
                            G Offline
                            George_George
                            wrote on last edited by
                            #15

                            Thanks Stuart, I have correct my code here, could you help to do a code review please? :-) http://www.codeproject.com/script/Forums/View.aspx?fid=1647&msg=2846175[^] regards, George

                            1 Reply Last reply
                            0
                            • G George_George

                              Thanks Naveen! I have proved we could expose both class and global variable by DLL and using your mentioned elegant way. :-) But I am not 100% confident. Here is my code, could you have a code review please? DLL Part:

                              // foo.h

                              #ifdef _DLLPROJ_
                              #define DLLEXP __declspec (dllexport)
                              #else
                              #define DLLEXP __declspec (dllimport)
                              #endif

                              DLLEXP class CFoo
                              {
                              public:

                              DLLEXP int foo1();
                              
                              DLLEXP int foo2();
                              

                              };

                              DLLEXP class CFooImpl : CFoo
                              {
                              public:

                              DLLEXP CFooImpl();
                              
                              DLLEXP int foo1();
                              
                              DLLEXP int foo2();
                              

                              };

                              // dllmain.cpp

                              #include "foo.h"

                              CFooImpl::CFooImpl()
                              {
                              return;
                              }

                              int CFooImpl::foo1()
                              {
                              return 100;
                              }

                              int CFooImpl::foo2()
                              {
                              return 200;
                              }

                              DLLEXP CFooImpl foo;

                              Hosting client part

                              // main.cpp

                              #include "foo.h"

                              DLLEXP CFooImpl foo;

                              int main()
                              {
                              CFooImpl foo1;

                              int i = foo.foo1();
                              i = foo.foo2();
                              
                              return 0;
                              

                              }

                              regards, George

                              N Offline
                              N Offline
                              Naveen
                              wrote on last edited by
                              #16

                              I have noted the below problem

                              George_George wrote:

                              DLLEXP class CFoo

                              This should be modified as class DLLEXP CFoo everthing else seems ok.

                              nave [OpenedFileFinder] [My Blog]

                              G 1 Reply Last reply
                              0
                              • G George_George

                                Thanks Naveen! I have proved we could expose both class and global variable by DLL and using your mentioned elegant way. :-) But I am not 100% confident. Here is my code, could you have a code review please? DLL Part:

                                // foo.h

                                #ifdef _DLLPROJ_
                                #define DLLEXP __declspec (dllexport)
                                #else
                                #define DLLEXP __declspec (dllimport)
                                #endif

                                DLLEXP class CFoo
                                {
                                public:

                                DLLEXP int foo1();
                                
                                DLLEXP int foo2();
                                

                                };

                                DLLEXP class CFooImpl : CFoo
                                {
                                public:

                                DLLEXP CFooImpl();
                                
                                DLLEXP int foo1();
                                
                                DLLEXP int foo2();
                                

                                };

                                // dllmain.cpp

                                #include "foo.h"

                                CFooImpl::CFooImpl()
                                {
                                return;
                                }

                                int CFooImpl::foo1()
                                {
                                return 100;
                                }

                                int CFooImpl::foo2()
                                {
                                return 200;
                                }

                                DLLEXP CFooImpl foo;

                                Hosting client part

                                // main.cpp

                                #include "foo.h"

                                DLLEXP CFooImpl foo;

                                int main()
                                {
                                CFooImpl foo1;

                                int i = foo.foo1();
                                i = foo.foo2();
                                
                                return 0;
                                

                                }

                                regards, George

                                S Offline
                                S Offline
                                Stuart Dootson
                                wrote on last edited by
                                #17

                                Aside from the issue Naveen showed you, IIRC you don't need to DLLEXP the class and the classes methods - one or the other, that's all that's needed really. I tend to DLLEXP the methods, as you have better control over what precisely is exported.

                                G 1 Reply Last reply
                                0
                                • N Naveen

                                  I have noted the below problem

                                  George_George wrote:

                                  DLLEXP class CFoo

                                  This should be modified as class DLLEXP CFoo everthing else seems ok.

                                  nave [OpenedFileFinder] [My Blog]

                                  G Offline
                                  G Offline
                                  George_George
                                  wrote on last edited by
                                  #18

                                  I think they should be the same? It compiles and runs well in VS. :-) regards, George

                                  1 Reply Last reply
                                  0
                                  • S Stuart Dootson

                                    Aside from the issue Naveen showed you, IIRC you don't need to DLLEXP the class and the classes methods - one or the other, that's all that's needed really. I tend to DLLEXP the methods, as you have better control over what precisely is exported.

                                    G Offline
                                    G Offline
                                    George_George
                                    wrote on last edited by
                                    #19

                                    Hi Stuart, I have tried that if I only mark dllexport on class and not on methods, the methods could not be found during link process. So, I think we have to mark both. Could you have a try please? regards, George

                                    S 1 Reply Last reply
                                    0
                                    • G George_George

                                      Hi Stuart, I have tried that if I only mark dllexport on class and not on methods, the methods could not be found during link process. So, I think we have to mark both. Could you have a try please? regards, George

                                      S Offline
                                      S Offline
                                      Stuart Dootson
                                      wrote on last edited by
                                      #20

                                      I have an awful lot of deployed code that uses this mechanism - here's a sample: #if!defined(COMMONLIB_API) #ifdef COMMONLIB_EXPORTS #define COMMONLIB_API __declspec(dllexport) #else #define COMMONLIB_API __declspec(dllimport) #endif #endif namespace MyAppLibrary { class MessageReporter { public: //ctor COMMONLIB_API MessageReporter(); //Add new reporting function COMMONLIB_API static void AddReportFunction(ReportFnPtr func); //Set MessageReporter Level on or off COMMONLIB_API static void SetReporterLevel(Level lev, bool on); //Set all levels to on COMMONLIB_API static void AllLevelsOn() {repLevels=~0;} //Set all levels to off COMMONLIB_API static void AllLevelsOff() {repLevels=0;} }; }; Is it possible you haven't exported necessary constructors?

                                      G 1 Reply Last reply
                                      0
                                      • S Stuart Dootson

                                        I have an awful lot of deployed code that uses this mechanism - here's a sample: #if!defined(COMMONLIB_API) #ifdef COMMONLIB_EXPORTS #define COMMONLIB_API __declspec(dllexport) #else #define COMMONLIB_API __declspec(dllimport) #endif #endif namespace MyAppLibrary { class MessageReporter { public: //ctor COMMONLIB_API MessageReporter(); //Add new reporting function COMMONLIB_API static void AddReportFunction(ReportFnPtr func); //Set MessageReporter Level on or off COMMONLIB_API static void SetReporterLevel(Level lev, bool on); //Set all levels to on COMMONLIB_API static void AllLevelsOn() {repLevels=~0;} //Set all levels to off COMMONLIB_API static void AllLevelsOff() {repLevels=0;} }; }; Is it possible you haven't exported necessary constructors?

                                        G Offline
                                        G Offline
                                        George_George
                                        wrote on last edited by
                                        #21

                                        But if you only expose class not expose methods, the methods could not be found when linking the client of the DLL (link error, unresolved symbols related to the methods). Could you have a try? I have tried. regards, George

                                        S 1 Reply Last reply
                                        0
                                        • G George_George

                                          But if you only expose class not expose methods, the methods could not be found when linking the client of the DLL (link error, unresolved symbols related to the methods). Could you have a try? I have tried. regards, George

                                          S Offline
                                          S Offline
                                          Stuart Dootson
                                          wrote on last edited by
                                          #22

                                          DLL interface defined in a.h

                                          a.h

                                          #if !defined(__A_H__) #define __A_H__ #if!defined(A_API) #ifdef A_EXPORTS #define A_API __declspec(dllexport) #else #define A_API __declspec(dllimport) #endif #endif class A_API A { public: A(); A(int a); void DoSomething(int b); int Result() const; private: int a_; }; #endif // !defined(__A_H__) DLL implemented in a.cpp and built with cl -EHsc -LD a.cpp

                                          a.cpp

                                          #include <windows.h> #define A_EXPORTS #include "a.h" BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; } A::A() : a_(0) {} A::A(int a) : a_(a) {} void A::DoSomething(int b) { a_ += b; } int A::Result() const { return a_; }
                                          DLL used in b.cpp, built with cl -EHsc b.cpp a.lib:

                                          b.cpp

                                          #include <iostream> #include "a.h" int main(int argc, char** argv) { A a(argc); a.DoSomething(3); std::cout << a.Result() << std::endl; } Builds fine, runs OK and even produces the right result...which is nice.

                                          modified on Saturday, December 20, 2008 6:19 AM

                                          G 1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups