★ TouchArcade needs your help. Click here to support us on Patreon.

Need help with game dev issue (xcode)

11-04-2010, 01:27 PM
#1
Joined: Sep 2009
Posts: 148
Need help with game dev issue (xcode)

Heya all,

I'm having a pretty frustrating "Duplicate Symbol" issue that I can't seem to find a solution for.

First of all, let me say that I'm not sure if what I'm doing is even valid (well at least it's working).
I started the project with the standard Universal template and then added the openGL ES layer to it.
Everything eventually got to run nice and smooth on both devices so I started implementing the actual game mechanics and this is where the trouble began.

Basically, I have 2 global variables that are CGpoints I use to communicate with my touch control functions in EAGLView (I can't get those functions to work anywhere else but I figured I would look more deeply into it later since I suck terribly at understanding obj C atm).
I have a c++ class "Player" used locally in my setup function for testing.
All is working fine till this point.

Now I want to declare two more global variables of type "Player" so I can initialize them in my setup function and use them anywhere I please.

So:
1. I move the #import "Player.h" from ES1Renderer.mm to ES1Renderer.h so I can make my globals.
2. I "convert" EAGLView to support C++ (since it imports ES1Renderer.h).

This is where I get the "duplicate symbol" error message (The symbol being the first global variable declared in ES1Renderer.h).

However, global variables work fine if I don't change EAGLView's sourcetype to cpp/objcpp (but then I can't use my class)

I use "import" because I read somewhere that it also acts as an include guard.
I do all my code in ES1Renderer (no ES2 yet) (apart from touches in EAGLView).
I use its init function to sneak in calls to my setup functions (setup of game world, vbos, textures, models, etc...) and I use its Render function to sneak in calls to my game functions (calculate character actions, collision detection, etc...).

Is this wrong practice ?
Anyone have any clue on what I'm doing wrong or maybe what I could do better so I can get on the right track ?

Anyways, forgive me if this was painful to read, english isn't my mother tongue and I'm pretty tired
Let me know if you need some additional information

Cheers

Last edited by Ezak; 11-04-2010 at 01:33 PM.
11-04-2010, 01:51 PM
#2
I'll say up-front that I didn't read all of your post because it was a little lengthy but for the "duplicate symbol" error you basically have 2 options.

1) Change the name of one of the global vars so that it is not a duplicate. This is the simple approach to fixing it.

2) If you need/want to use global variables all over the place without running into this issue again then create a GlobalManager singleton and just include the header file of this class for anything needing to access these specific variables.

Here is a link to a simple example of a data manager if you want to see how it is implemented. http://pastie.org/541191 BTW, This is not my code but I have used this as an example to build my own global manager system :-)

iPhone/iPod Touch Apps by Tiny Tech Studios
11-04-2010, 02:07 PM
#3
Joined: Sep 2009
Posts: 148
Quote:
Originally Posted by TinyTechnician View Post
I'll say up-front that I didn't read all of your post because it was a little lengthy but for the "duplicate symbol" error you basically have 2 options.

1) Change the name of one of the global vars so that it is not a duplicate. This is the simple approach to fixing it.

2) If you need/want to use global variables all over the place without running into this issue again then create a GlobalManager singleton and just include the header file of this class for anything needing to access these specific variables.

Here is a link to a simple example of a data manager if you want to see how it is implemented. http://pastie.org/541191 BTW, This is not my code but I have used this as an example to build my own global manager system :-)
That's a great place to start, i'll have a look at the singleton
Thanks
11-04-2010, 06:25 PM
#4
Joined: Sep 2009
Location: Vancouver, Canada
Posts: 977
Send a message via MSN to MindJuice Send a message via Skype™ to MindJuice
Quote:
Originally Posted by Ezak View Post
This is where I get the "duplicate symbol" error message (The symbol being the first global variable declared in ES1Renderer.h).
It is not good practice to include global variable instances in .h files.

The protection afforded by import only extends across the file currently being compiled. Each file that imports your .h file gets "included" again and therefore creates another global symbol, which results in duplicate symbols.

Instead, you can include extern references to your globals in the .h, but the actual variable should be declared once in a .cpp file (or .m or .mm or whatever you prefer).

Alternatively, as suggested, consider a singleton, but again, you have to ensure that the single instance is not located in a header file.
11-05-2010, 06:34 AM
#5
Joined: Sep 2009
Posts: 148
Quote:
Originally Posted by MindJuice View Post
It is not good practice to include global variable instances in .h files.

The protection afforded by import only extends across the file currently being compiled. Each file that imports your .h file gets "included" again and therefore creates another global symbol, which results in duplicate symbols.

Instead, you can include extern references to your globals in the .h, but the actual variable should be declared once in a .cpp file (or .m or .mm or whatever you prefer).

Alternatively, as suggested, consider a singleton, but again, you have to ensure that the single instance is not located in a header file.
Thank you, that explains a lot

Just to make sure I get this right (can't test it atm). I can declare the global variables using extern in any number of header files, and then define the global variables without extern in a unique source file ?

As in, something like this ?
Code:
// I put this in some "global variable" source file
int myGlobal; 

//I put this in my header where I need to use the global
extern int myGlobal;
Cheers

Last edited by Ezak; 11-05-2010 at 06:54 AM.
11-05-2010, 06:54 AM
#6
yup.