Archived

This topic is now archived and is closed to further replies.

Koen

c++ link error

Recommended Posts

I have the following header and source files: test.h :
#ifndef TEST_H
#define TEST_H

#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>
#include <gl\glext.h>


PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = NULL;
PFNGLMULTITEXCOORD2FARBPROC	glMultiTexCoord2fARB = NULL;
PFNGLCLIENTACTIVETEXTUREARBPROC	glClientActiveTextureARB = NULL;

class test	{
public:
	test();
	static bool init;

};

#endif
 
test.cpp :
#include "test.h"
test::test()	{
	if(!init)	{
		init=true;
		glActiveTextureARB   = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB");
		glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) wglGetProcAddress("glMultiTexCoord2fARB");
		glClientActiveTextureARB= (PFNGLCLIENTACTIVETEXTUREARBPROC) wglGetProcAddress("glClientActiveTextureARB");
	}
}

bool test::init=false;
 
When I compile these files with a hello-world windows program, everything works fine. But when I add #include "test.h" to main.cpp, the compiler (Codewarrior) tells me ''Multiple definitions of symbol: ?glActiveTextureARB@@3P6GXI@ZA in main.cpp, test.cpp''. The two other gl-functions give similar link-errors. I really don''t see how this is possible. Does anybody know what is wrong? (I think all includes and libraries are declared/linked correctly. If I try to initialize the three OpenGL multitexturing functions in main.cpp, everything works fine) PS: apologies for the lengthy code.

Share this post


Link to post
Share on other sites
Don''t declare variables in headers. For example (to modify your code)
test.h:

#ifndef TEST_H
#define TEST_H

// ...

extern PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = NULL;
extern PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB = NULL;
extern PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB = NULL;

class test {
// ...
};

#endif

test.cpp:

#include "test.h"

PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = NULL;
PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB = NULL;
PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB = NULL;

test::test() {
// ...
}

bool test::init=false;


Share this post


Link to post
Share on other sites
quote:
Original post by Koen
Why can''t variables be declared in header files?

Just think about it: in the place of the include preprocessor command, the file referenced is ''placed'' where the include command was. If you do this with a header than declares a variable, you''ll get one instance of that variable in each source file that includes that header. The linker gets confused because it doesn''t know which one of the identical variables you want to use, which is the error. By putting extern infront of the variable, we basically say ''this variable exists, but not here''. The linker only finds a single copy of each variable in a single source file, and every is fine.

Share this post


Link to post
Share on other sites
Isn't that what #ifndef #define #endif is for? I thought this construction makes sure every header file gets included only once. The multiple definitions error doesn't occur when inlining a function (which is declaration and definition in one). Oh well, maybe I should read a little more about compiling and linking :-)
Thanks again.

[edited by - Koen on July 18, 2002 7:52:43 AM]

Share this post


Link to post
Share on other sites
The include guards only make sure that header files don''t get included more than once PER C SOURCE FILE. That means if you have variables declared in headers you''ll get a copy in each C file, and the linker will moan at you as demonstrated.


Helpful links:
How To Ask Questions The Smart Way | Google can help with your question | Search MSDN for help with standard C or Windows functions

Share this post


Link to post
Share on other sites