Thread: MinGW says undef. references while building my dll

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

    MinGW says undef. references while building my dll

    Hi,

    I'm trying to build a dll from a .cpp file with MinGW. The problem is, that this .cpp file uses symbols (types) from the program it will be linked to.
    while this seems to be no problem under linux, MinGW complains about the undefined references.

    here is a little example:

    Code:
    #include "classFromMainApp.h"
    
    #include myDll.h
    
    ...
    
    extern "C"
    {
    
    EXPORT someFunction( classFromMainApp& _cfma )
    {
       cfma.doStuff();
    }
    
    } // extern "C"
    When I compile it, which works fine:
    Code:
    gcc -c -DBUILD_DLL myDll.c
    But If I link:
    Code:
    gcc -shared -o myDll.dll myDll.o -Wl,--out-implib,libmyDll.a
    i'm getting erros saying
    Code:
    :myDll.cpp:(.rdata$_ZTVN6entity10myDllE[vtable for myDLL]+0x18): undefined reference to `classFromMainApp::doStuff()'

    But I want to let MinGW know that it gets this symbols as soon as its loaded with LoadLibrary() but it can't get them now.

    What I'm doing wrong?

    Thank you!

  2. #2
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    I created a little example in C, maybe that helps someone to understand my problem:

    the problem occours as soon as I comment in //appFct(); in dllfct.c

    Code:
    //dllfct.h
    
    #ifdef BUILD_DLL
    // the dll exports
    #define EXPORT __declspec(dllexport)
    #else
    // the exe imports
    #define EXPORT __declspec(dllimport)
    #endif
    
    #include "hello.h"
    
    // function to be imported/exported
    EXPORT void tstfunc (void);
    Code:
    // dllfct.c
    
    #include <stdio.h>
    #include "dllfct.h"
    
    EXPORT void tstfunc (void)
    {
      //appFct();
      printf ("Hello\n");
    }
    Code:
    // hello.h
    
    void appFct();
    Code:
    // hello.c
    
    #include "dllfct.h"
    
    void appFct()
    {
         printf("app here\n");
    }
    
    int main ()
    {
        tstfunc ();
        return (0);
    }
    Code:
    //build:
    
    gcc -c hello.c
    gcc -c -DBUILD_DLL dllfct.c
    gcc -shared -o tst.dll dllfct.o  // ERROR undefined reference to appFct()
    gcc -o out.exe hello.o -L./ -ltst

  3. #3
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    shouldn't it be tst.lib and not dll in the linker params?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  4. #4
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    I took the commands from http://www.mingw.org/docs.shtml. they say .dll

  5. #5
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    maybe I need some parameter to delay the lookup of the symbols under windows os?

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    I don't know if all platforms even support what you're trying to do. How many different calls back into the main program does your DLL have to make? Does it know "a lot" about the other program or is it merely making a few callbacks?

    If all you're doing is making callbacks, you can remove the link-time dependency by creating some kind of callback structure and registering that with the DLL. The DLL then calls back via a function pointer. That way, it does not need to know the symbols in the main program.

  7. #7
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Hi brewbuck,

    only 1 or 2 callbacks for now. the main reason the DLL knows "a lot" about the other program is that the DLL derives classes from an abstract base class that is defined in the main programm.


    main-programm: defines class base{};
    |
    |
    now it loads DLLs, which define classes that derive from base. the number of this DLLs can increase, the types they derive is not known at compile time of the main programm.

    shouldn't many programs with an plugin-system handle things that way?
    Last edited by pheres; 03-29-2007 at 10:54 AM.

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by pheres View Post
    now it loads DLLs, which define classes that derive from base. the number of this DLLs can increase, the types they derive is not known at compile time of the main programm.

    shouldn't many programs with an plugin-system handle things that way?
    Yes, but these typically work through COMPLETELY abstract base classes (what would be called an "interface" in Java), so that only the base class definition is needed by the DLL. There are no "real" functions in the base class.

    So something like this:

    Code:
    // File base_class.h
    
    class base_class
    {
    public:
        base_class() {}
        virtual ~base_class() {}
    
        virtual int someInterfaceMethod(int a) = 0;
        virtual void someOtherMethod(int b) = 0;
    };
    Note the presence of inline constructor and destructor, with virtual destructor. Also note the two fully abstract methods. This prevents you from accidentally trying to instantiate a base_class. It must be derived, and the methods implemented, for it to be instantiated.

    This way, the only thing the DLL needs to know about is the base_class.h header file. But as soon as you put "real" code into the base_class, you will have this linker problem again. So the question is, do you need some shared code in the base class, or is this purely an interface?

    EDIT: Also, be aware that you will not be able to construct the derived objects via their constructors, from within the main program. It has no idea what the parameters to these constructors might be, nor does it know the name of the derived class. So you create some kind of "Factory" function in the DLL, probably with a standard name like "CreatePluginInstance" or somesuch, and this function constructs a derived object with new, using the proper constructor parameters, and returns it.
    Last edited by brewbuck; 03-29-2007 at 11:08 AM.

  9. #9
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    yes, I'm already using a factory method (and it works fine in the linux implementation)

    while my base class really is abstract (it has at least one pure virtual function) the trouble is, it has a lot functions with default implementations what probably fit most of the time for the whole family of classes. it would really make my depressive if I would find out now, what my DLLs could never use these default implementations. it is intended that in future other programmers add DLLs what can rely of a strong base of ready functionality.

  10. #10
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    I think that this sort of thing is usually solved on Windows via COM objects. But this is getting way out of my area of knowledge so I'll leave it at that.

    Suffice it to say, the model is quite different on Linux and Windows.

  11. #11
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Ok, I'm thanking for your efforts anyhow!

  12. #12
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    in the case someone is interested in the solution (there a several possibilities) i found meanwhile to build DLLs what references back to the mainapp:

    1. factor out all comonly used symbols from exe and dll in a seperate dll und link that one in both (to much work in my case)

    I'm using the next now:
    2. build first the exe together with an import library. there is a command line linker option to build the import lib AND to export all symbols from the exe in it. then build the DLL with the import lib from the exe at command line

    3. don't use symbols direct from the exe but instead lookup function pointers from the exe with getprocadress(). (hardly possible in my case because i'm not just using functions from the exe but let a class in the dll derive from a class from the main app.)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pointer references corrupted via DLL (Cygwin)
    By rockpaandi in forum C Programming
    Replies: 6
    Last Post: 03-16-2009, 06:50 PM
  2. How to solve warnings that appear when building my DLL...
    By starcatcher in forum Windows Programming
    Replies: 6
    Last Post: 12-14-2008, 11:47 AM
  3. Replies: 3
    Last Post: 04-16-2007, 12:02 PM
  4. Round Robin Scheduling using c.
    By eclipt in forum C Programming
    Replies: 8
    Last Post: 12-28-2005, 04:58 PM
  5. dll communicating between each other
    By cloudy in forum C++ Programming
    Replies: 5
    Last Post: 06-17-2005, 02:20 AM