[C++] Unresolved externals!

Started by
3 comments, last by Zahlman 14 years, 10 months ago
Alright, so i have a program that initializes a few character sequences like this: Buttons.h

#ifndef BUTTONS_H
#define BUTTONS_H

#include "SDL.h"

extern char Player_1G_up[];
extern char Player_1G_down[];

#endif


Buttons.cpp

#include "SDL.h"
#include "buttons.h"
void Player_1_Keys()
{
	CIniFile ini;
	ini.Load("config.ini");
	char Player_1G_up =		(char)ini.GetSection("Player_Buttons")->GetKey("Player_1G_up")->GetValue().c_str();
	char Player_1G_down =		(char)ini.GetSection("Player_Buttons")->GetKey("Player_1G_down")->GetValue().c_str();
}



with this code, i get the following errors:

1>Linking...
1>MSVCRTD.lib(cinitexe.obj) : warning LNK4098: defaultlib 'msvcrt.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
1>menu.obj : error LNK2001: unresolved external symbol "char * Player_1G_start" (?Player_1G_start@@3PADA)
1>menu.obj : error LNK2001: unresolved external symbol "char * Player_1G_up" (?Player_1G_up@@3PADA)
1>menu.obj : error LNK2001: unresolved external symbol "char * Player_1G_down" (?Player_1G_down@@3PADA)
1>menu.obj : error LNK2001: unresolved external symbol "char * Player_1G_exit" (?Player_1G_exit@@3PADA)
1>menu.obj : error LNK2001: unresolved external symbol "char * Player_1G_green" (?Player_1G_green@@3PADA)
1>C:\Documents and Settings\User\Desktop\C++\Shredding_Legend\Debug\Shredding_Legend.exe : fatal error LNK1120: 5 unresolved externals



Now, it says menu.obj, but in the menu.cpp file, the only thing i did was call for that char..

//If a key was pressed
if( event.type == SDL_KEYDOWN )
{
	//Set the proper message surface
	switch( event.key.keysym.sym )
	{
		//Down
		while( Player_1G_down ) //This file also include buttons.h
		{
			choice++;
			break;
		}
		//Up
		while( Player_1G_up )
		{
			choice--;
			break;
		}
	}
}



I cant figure out the problem, i have been trying for like 3 days now!
Advertisement
In Buttons.h, you declare Player_1G_up and Player_1G_down as objects of type array-of-char-of-indeterminate-length.

Where are the definitions of these objects? Neither I nor your linker can see them.
Quote:Original post by the_edd
In Buttons.h, you declare Player_1G_up and Player_1G_down as objects of type array-of-char-of-indeterminate-length.

Where are the definitions of these objects? Neither I nor your linker can see them.


lol, what?

even when i take out the brackets to make them non-array(?) type, it gives those same errors.
Moved to For Beginners.
1)

extern char Player_1G_up[];extern char Player_1G_down[];


This does not create those global variables. It simply makes a promise that you will set them up somewhere. You haven't set them up somewhere.

2)

void Player_1_Keys(){	CIniFile ini;	ini.Load("config.ini");	char Player_1G_up =		(char)ini.GetSection("Player_Buttons")->GetKey("Player_1G_up")->GetValue().c_str();	char Player_1G_down =		(char)ini.GetSection("Player_Buttons")->GetKey("Player_1G_down")->GetValue().c_str();}


a) The cast is wrong. When the compiler tells you that types don't match up, you need to pay attention and think about why they don't match up.

A char is not the same thing as a char*. The cast will take the address of the "string data" returned by the .c_str() function of the string, re-interpret it as a number, and try to stuff that number into an 8-bit value.

b) This would not assign anything to those global variables, even if you had set them up. When you put the type name in front of a variable name like that, you declare a new variable. Thus, you are assigning to local variables inside the function, not the globals.

c) Even if you fixed it so that you have a global variable of type char* (or char[], which is the same thing if you don't specify an array size), and fixed the function to assign to the global properly, it still wouldn't work, because after the function ends, the std::string instances no longer exist, and the pointers are garbage.

d) Even if you fixed it so that the global variables are char[SOME_SPECIFIC_SIZE], it still wouldn't work, because an assignment like "<array variable> = <pointer variable>" is illegal. You would need to copy the pointed-at data into the array with a function like strcpy().

e) Even if you did that, it still wouldn't really work properly, because the array size would put a limit on the string length, whereas std::string has no such limit (beyond the limits on the implementation's ability to address memory).

3) In short, std::string is your friend. Use it, instead of going out of your way to avoid it.



To sum up:

In the header, you should have something like:

extern std::string Player_1G_up, Player_1G_down;


And in the source file, something like:

std::string Player_1G_up, Player_1G_down;void Player_1_Keys() {	CIniFile ini;	ini.Load("config.ini");	Player_1G_up = ini.GetSection("Player_Buttons")->GetKey("Player_1G_up")->GetValue();	Player_1G_down = ini.GetSection("Player_Buttons")->GetKey("Player_1G_down")->GetValue();}


This topic is closed to new replies.

Advertisement