Thread: Help! Linker can't find definitions in ".a" library!

  1. #1
    Registered User
    Join Date
    Nov 2006
    Posts
    184

    Help! Linker can't find definitions in ".a" library!

    I wrote a DLL and created a ".a" library (with MinGW/GCC). Now I'm compiling a new DLL that uses the functions and classes defined in that library. However, I get multiple errors:

    "Undefined reference to '.....'"

    What is causing this?

  2. #2
    Registered User
    Join Date
    Nov 2006
    Posts
    184
    I got it to work but I had to include the object files in addition to the library. Why is this? I thought I could compile it with just the lib file and DLL?

  3. #3
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    without code, the majik 8 ball says 'help is doubtful'.

  4. #4
    Registered User
    Join Date
    Nov 2006
    Posts
    184
    I'm using ant to make it, so i apologize but I think the name of the tags should be fairly clear.

    Code:
    <cc
    	link="shared"
    	outtype="shared" 
    	multithreaded="true"
    	optimize="speed"
    	objdir="."
    	outfile="TryIt"
    >
    	<compilerarg value="-Wall"/>
    	<compilerarg value="-fno-strict-aliasing"/>
    
    	<linker name="gcc">
    		<linkerarg value="--kill-at"/>
    		<linkerarg value="-oTryIt.dll"/>	
    
    		<!-- 
    			If I include these, it compiles. If instead I include 
    			the library and NOT these object files, it cannot
    			find the definitions.
    		-->
    		<linkerarg value="TestClass.o" />
    		<linkerarg value="Globals.o" />
    	</linker>
    
    	<sysincludepath location="C:/Program Files/MinGW/Beta"/>
    	<sysincludepath location="."/>
    
    	<fileset dir="." includes="*.cpp"/>
    
    	<libset libs="stdc++" />
    </cc>
    And my CPP file includes the header with all the function/class declarations:

    #include <Test.h>

    (All the classes that are in the lib were also compiled with that same header included in them as well)

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    I've never used MinGW, I always use VC++ on Windows; but .a is a UNIX extension. Are you sure it's building a library for Windows which should be .lib?

  6. #6
    Registered User
    Join Date
    Nov 2006
    Posts
    184
    Quote Originally Posted by cpjust View Post
    I've never used MinGW, I always use VC++ on Windows; but .a is a UNIX extension. Are you sure it's building a library for Windows which should be .lib?
    It shouldn't matter since I'm using GCC to create the dll and run the program, right?

  7. #7
    Registered User
    Join Date
    Nov 2006
    Posts
    184
    Quote Originally Posted by cpjust View Post
    I've never used MinGW, I always use VC++ on Windows; but .a is a UNIX extension. Are you sure it's building a library for Windows which should be .lib?
    I created a ".lib" from the ".def" file using MSVC's lib tool and it still gives me an "undefined reference" error!

  8. #8
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    ok, you still havent posted the code. Post the contents of Test.h and maybe we can help you.

  9. #9
    Registered User
    Join Date
    Nov 2006
    Posts
    184
    Quote Originally Posted by abachler View Post
    ok, you still havent posted the code. Post the contents of Test.h and maybe we can help you.
    It's basically:

    Code:
    #include <iostream>
    #include <vector>
    #include <sstream>
    
    #ifndef MYHEADER_
    
    #define MYHEADER_
    
    
    //All the basic functions are like this
    extern void changeType(std::string name, std::vector<std::string>& vec);
    
    //I have a few templated functions
    template <typename T> void changeType(T& type)
    {
         ...elided...
    }
    
    //I have a bunch of class declarations without the implementations
    class SomeClass
    {
    public:
         void doSomething();
    };
    #endif
    All the class functions were implemented in <class_name>.cpp files and the extern functions in functions.cpp. I then compiled it into one DLL and made a lib file from that (as well as the object files).
    Last edited by 6tr6tr; 04-17-2008 at 03:05 PM.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    OK this is somewhat bothering.
    What purpose does the "extern" have before the function?

    Further, remember that to access functions in a dll, they must be exported, either via a .def file (type the names of the functions to export) or via __declspec(export)/__declspec(import). If you don't, you get errors.
    You cannot export unspecialized templates. Say, changeType. You can't export changeType, but you can export changeType<int>.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Registered User
    Join Date
    Nov 2006
    Posts
    184
    Quote Originally Posted by Elysia View Post
    OK this is somewhat bothering.
    What purpose does the "extern" have before the function?
    When I'd first compiled the classes (each includes that header file in it) I kept getting "undefined reference" errors so i read that I need to put "extern" before the functions in order to compile and it worked (since the header has the function declarations but not the implementation).

    For example, I had TestClass.cpp and SomeExceptionClass.cpp and a few others and each had that same header file (since they all refer to each other and use the same global functions) and had the function implementations in functions.cpp. When I compiled I got errors until I put extern on everything except the template functions and the class declarations.

    Quote Originally Posted by Elysia View Post
    Further, remember that to access functions in a dll, they must be exported, either via a .def file (type the names of the functions to export) or via __declspec(export)/__declspec(import). If you don't, you get errors.
    I didn't know that, but if that's true then why does my compiling of this new program work when I do either one of the following:

    1. Include the DLL via -lTheDLL for the linker
    2. Include the object files in the linker's search path

    I didn't do any writing of that export but it still works. Could this be because my linker/gcc settings put it in for me since I said it's a shared DLL?

    Quote Originally Posted by Elysia View Post
    You cannot export unspecialized templates. Say, changeType. You can't export changeType, but you can export changeType<int>.
    I'm not sure what you mean by that since I was able to use that template function in another DLL ( when I do either #1 or #2 from above). Why am I able to do that if I can't export it? And why can't you export it?

    Thanks for all your help and time!
    Last edited by 6tr6tr; 04-18-2008 at 07:57 AM.

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by 6tr6tr View Post
    When I'd first compiled the classes (each includes that header file in it) I kept getting "undefined reference" errors so i read that I need to put "extern" before the functions in order to compile and it worked (since the header has the function declarations but not the implementation).

    For example, I had TestClass.cpp and SomeExceptionClass.cpp and a few others and each had that same header file (since they all refer to each other and use the same global functions) and had the function implementations in functions.cpp. When I compiled I got errors until I put extern on everything except the template functions and the class declarations.
    Extern is only needed for global variables that are not defined in the current source file they're used. It's not needed for functions.

    I didn't know that, but if that's true then why does my compiling of this new program work when I do either one of the following:

    1. Include the DLL via -lTheDLL for the linker
    2. Include the object files in the linker's search path

    I didn't do any writing of that export but it still works. Could this be because my linker/gcc settings put it in for me since I said it's a shared DLL?
    I don't know how gcc works... Unfortunately, I don't.

    I'm not sure what you mean by that since I was able to use that template function in another DLL ( when I do either #1 or #2 from above). Why am I able to do that if I can't export it? And why can't you export it?
    Code:
    template<typename T> void foo(T myarg) { }
    This is a template function. However, the compiler will not generate any code for this function. To generate code, you must first call the function with an appropriate argument. When you do, the compiler will know the type of T and therefore be able to generate code for the function.

    When we refer to a templated function, in this case, foo, we can do it in two ways. We can simply type "foo". This is referred to as unspecialised, because you didn't specify any type. In many instances, this is illegal. We must one function (since foo can be generated as many functions). So we can export, for example, foo<int> (a specialized template).

    Of course, you can simply define these templates in the headers (and implement them) and if you include that file, the compiler can generate code within your program. This means the function won't reside in the dll, but your application, so naturally it works even if it isn't exported.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Registered User
    Join Date
    Nov 2006
    Posts
    184
    Quote Originally Posted by Elysia View Post
    Extern is only needed for global variables that are not defined in the current source file they're used. It's not needed for functions.
    That's just not correct. My functions are delcared in the header and defined/implemented in "functions.cpp." If I take off the extern keyword on the function declarations (in the header) it doesn't compile/link and it shouldn't since the definition is in a diff. file.


    Quote Originally Posted by Elysia View Post
    This is a template function...Of course, you can simply define these templates in the headers (and implement them) and if you include that file, the compiler can generate code within your program. This means the function won't reside in the dll, but your application, so naturally it works even if it isn't exported.
    Yeah, sorry, that's what I meant for the template functions. They're all in the header, not in the DLL.

    Thanks again for helping me figure this out.

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by 6tr6tr View Post
    That's just not correct. My functions are delcared in the header and defined/implemented in "functions.cpp." If I take off the extern keyword on the function declarations (in the header) it doesn't compile/link and it shouldn't since the definition is in a diff. file.
    Yes, that explains how I use different files in all my projects and it compiles fine without the extern keyword.
    Actually, the linker will search through all object files when searching for a function. The difference is a variable. You can't redefine it, so you must use something to tell the compiler it exists, yet not redefine it. Therefore the "extern" keyword exists.
    This is not needed for functions, because declarations are not definitions. They do not produce any code.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    i dont know Vicious's Avatar
    Join Date
    May 2002
    Posts
    1,200
    Perhaps the MSVC++ compiler/linker takes care of the extern stuff? There are many things you can do with microsoft's compiler that GCC will not let you do. Just thought I'd toss that in there: continue
    What is C++?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem building Quake source
    By Silvercord in forum Game Programming
    Replies: 16
    Last Post: 07-11-2010, 09:13 AM
  2. university library
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 09-10-2003, 03:05 PM
  3. linked list recursive function spaghetti
    By ... in forum C++ Programming
    Replies: 4
    Last Post: 09-02-2003, 02:53 PM
  4. Won't Return pointer, i can't find why...
    By ss3x in forum C++ Programming
    Replies: 2
    Last Post: 02-28-2002, 08:50 PM
  5. Linker errors with simple static library
    By Dang in forum Windows Programming
    Replies: 5
    Last Post: 09-08-2001, 09:38 AM