# Calling externally defined funcs from DLL?

This topic is 2815 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm trying to build a DLL and can't get it to link because of an undefined reference... please keep reading.

I'm writing a program and I have the need to access functions that are only defined in the main.cpp source file from another source file. I declare a prototype in the header or source file in which I'll need to call the function, like so...

extern void Con_print(const char* fmt, ...);

When I try to link and create the DLL I get the following error:

 MyGame.o:MyGame.cpp:(.text+0xab): undefined reference to Con_print(char const*, ...) collect2: ld returned 1 exit status 

I'm using g++ to compile and link, in MinGW in Windows 7.

Here is how I'm attempting to compile and link the DLL

 g++ -c -I"./headers/" src/Game.cpp -o Game.o g++ -c -I"./headers/" gameMod/MyGame.cpp -o MyGame.o g++ -shared -o MyGame.dll Game.o MyGame.o 

Here is the code in its simplest form:

main.cpp
 ... void Con_print(const char* fmt, ...) { ... // func body ... } ... 

Game.h
 extern void Con_print(const char* fmt, ...); class Game { ... }; 

MyGame.h
 #include "Game.h" class MyGame : public Game { ... void example(); ... }; 

MyGame.cpp
 ... void MyGame::example() { Con_print("Here's my example: %s", "more input"); } ... 

From within MyGame->example(), I call Con_print as you can see above, this particular call is what the linker complains about, if I comment this call out (not the declaration) the DLL compiles normally and I am able to load it at runtime as expected. This functionality works perfectly in Linux (with dynamically loading of a .so) and I am able to call my externally defined functions, but I can't get the DLL built in Windows because of this 'undefined reference'.

I've tried compiling this in Visual Studio 2010 Express and I get an identical error to that which I get from g++.

I'm wondering if there is another way to build the DLL or if there is a way I can get g++ to let this undefined reference slide?

##### Share on other sites
Since main.cpp has the actual function definition, you should be linking in its object file as well.

##### Share on other sites
When I include main.o in the linking, the linker then wants to know about all of the other objects used in that file. Aside from that, I don't want to roll the whole application into the dll.

##### Share on other sites
In that case you should probably move the Con_print function and any functions it depends on to another cpp file and link the object file coming from that to the DLL.

##### Share on other sites
To do that would mean moving other things into the scope of the DLL which I also don't want to do. This functionality needs to be removed from the DLL so that the end users of my Class don't have to deal with explicitly defining and linking the Console portion of this application.

##### Share on other sites
The COFF model does not allow unresolved references in dynamically linked objects. This has nothing to do with what toolchain you're using. You just can not create a DLL that assumes a symbol will be present on the object it will get linked into in the future. Your dymaic dependency list must be a directed acyclic graph.

The traditional way to provide this functionality is to refactor the stuff you currently have in your "main" object into another DLL that gets linked in to both your DLL and your application. Alternatively, you may be able to fudge around with .LIB stubs, but if you break it you own it.

You can read more background here under "Import Tables".

##### Share on other sites
You can also just pass a function pointer to the DLL as an initialization step.

##### Share on other sites

The COFF model does not allow unresolved references in dynamically linked objects. This has nothing to do with what toolchain you're using. You just can not create a DLL that assumes a symbol will be present on the object it will get linked into in the future. Your dymaic dependency list must be a directed acyclic graph.

The traditional way to provide this functionality is to refactor the stuff you currently have in your "main" object into another DLL that gets linked in to both your DLL and your application. Alternatively, you may be able to fudge around with .LIB stubs, but if you break it you own it.

You can read more background here under "Import Tables".

Thank you, I'll look at this closer when I'm out of work.

You can also just pass a function pointer to the DLL as an initialization step.

I was considering this as a workaround, it seems a little odd that I can't get the linker to just let it go. Bregma's post may shed some light on that. I was hoping to avoid having passing in a mess of references but I should still be able to hide the implementation from the end user this way so its an acceptable workaround.

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 21
• 13
• 18
• 25