Sign in to follow this  
skwee

Unresolved external symbol in c++ (exe + dll)

Recommended Posts

Hi, I got some problem that I just can't fix! I have the following class that is compiled into DLL
        /** Abstract application interface.
	*/
	class SKGE_API Application{
	protected:
		//Render::RenderDevice* m_RenderDevice; /**< Render device. */

		/** Input handler.
		*/
		//virtual void handleInput() = 0;

	public:

		/** Create application
		*/
		virtual void create() = 0;

		/** Destroy application.
		*/
		//virtual void destroy() = 0;

		/** Run application.
		*/
		//virtual void run() = 0;
	};




(includes, header guards and namespaces omitted) SKGE_API is defined as __declspec(dllexport) for library, and __declspec(dllimport) for the EXE This is in the EXE file:
class Demo1: public Application{
private:
	bool running;

public:
	void create(){

	}
};

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
	Demo1 app;
	app.create();

	/*app.run();

	app.destroy();*/

	return 0;
}




Or in short, there is an abstract class in the DLL from whom I inherit another class in the EXE, this is the error I got:
Error	1	error LNK2019: unresolved external symbol 
"__declspec(dllimport) public: __thiscall skge::Application::Application(void)"
 (__imp_??0Application@skge@@QAE@XZ) referenced in function "public: __thiscall
 Demo1::Demo1(void)" (??0Demo1@@QAE@XZ)	main.obj	Demo1

Error	2	fatal error LNK1120: 1 unresolved externals
C:\Documents and Settings\Dmitri\My Documents\Visual Studio 2008\Projects
\Skge\Debug\Demo1.exe	1	Demo1

I tried everything :( Where I wrong? Please don't mark threads 'solved' on this forum. [Edited by - jpetrie on June 8, 2009 10:04:25 AM]

Share this post


Link to post
Share on other sites
Did you try giving Application an explicit default constructor and defining that in the DLL?

Share this post


Link to post
Share on other sites
Yes, the same error.
One more note: Application does not have a CPP file, its just an interface.

[EDIT] However if I create a CPP file for application where I create an empty constructor it works. Could some one explain me why I must have a cpp file?

Share this post


Link to post
Share on other sites
How the heck did you define the default constructor in the DLL when you didn't have a .cpp file for it?

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
How the heck did you define the default constructor in the DLL when you didn't have a .cpp file for it?


oO


class SKGE_API Application{
public:
Application(){}
};


Sorry if it looks stupid, its the first time I write dll in C++.

Share this post


Link to post
Share on other sites
The C++ compiler compiles C++ files -- .cpp, et cetera. It does not compile .h files. So if there were no .cpp files in your DLL's project that included the header in which you defined the constructor, then the constructor was never defined.

Share this post


Link to post
Share on other sites
Quote:
Original post by jpetrie
The C++ compiler compiles C++ files -- .cpp, et cetera. It does not compile .h files. So if there were no .cpp files in your DLL's project that included the header in which you defined the constructor, then the constructor was never defined.

Yes I know, I just dont see the logic, why must define a constructor?
I mean, if I have two classes, the first is Interface and the seconds is a class that implement the interface, in case that they both in the same project I'm pretty sure it will work, so what is the difference between this case and what I did? The only difference is that the interface is defined in DLL file, but in fact the H file (in my case Application.h) is included in the main.cpp (in exe) so it should behave like a part of the exe project? Am I wrong?

Share this post


Link to post
Share on other sites
You must define a constructor because you declared one. In your application, you include some header, somewhere, that causes the compiler to believe there is a default ctor for Application (skge::Application::Application(void)). If you never define it, then the linker will of course never find it.

The code you have posted in the original post disagrees with your subsequent code. Post the real code.

Share this post


Link to post
Share on other sites
But I did not declared a constructor...

Application.h in DLL project
[source lang="cpp]
#ifndef SKGE_APPLICATION_H_
#define SKGE_APPLICATION_H_

#include "SkgeLibrary.h"
#include "SkgeRenderDevice.h"

namespace skge{

/** Abstract application class.
*/

class SKGE_API Application{
protected:

public:
//Application();

virtual void create() = 0;
virtual void destroy() = 0;
virtual void run() = 0;
};
}

#endif



Main.cpp in EXE project

#include <windows.h>

#include "../Skge/src/Skge.h"
#include "../Skge/src/SkgeApplication.h"
#include "../Skge/src/SkgeOpenGLRenderDevice.h"

#include <SDL/SDL.h>

using namespace skge;


class Demo1: public Application{
public:
//Demo1(){}

void create(){
}

void destroy(){
}

void run(){
}
};

#pragma comment(lib, "../Debug/skge_d.lib")



int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
Demo1 app;
app.create();

app.run();

app.destroy();

return 0;
}


Notice the the constructor is commented in the Application.h file. In this case the EXE project would not compile and Ill get error as posted in the original post.

As you see I did not defined any constructor and I don't have CPP file for Application (its just an interface, nothing to implement).

Now scenario 2:
If I just add an Appliation.cpp file with the following content:

#include "SkgeApplication.h"

namespace skge{

}


It will work. I don't see why or/and how.

Share this post


Link to post
Share on other sites
The compiler will automatically define certain functions for you if you don't define them yourself. This includes the default constructor if a class doesn't include any user defined constructors, a copy constructor if a class doesn't include any user defined copy constructors, an assignment operator if a class doesn't include any user defined assignment operators and a destructor if a class doesn't include a user defined destructor. Since you defined your class as DLL exported/imported, the application won't try to define them itself and will try to grab the definition from the DLL, and without a single source file in your DLL, it can't do any of that since it doesn't have the opportunity to generate any code.

Share this post


Link to post
Share on other sites
Yes I know about the stuff that compiler generates.

Anyway thanks fro the explanation I think I got it now!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this