Sign in to follow this  
yboris

Sharing Variables Between Forms (Visual C++ 2008)

Recommended Posts

yboris    122
Hello my dear friend; I have spent over 4 hours and my friend (who knows C++ far better than me) another hour trying to get a simple thing to work: share variables across "Windows Forms". Simple C++ doesn't work as I'm using Visual C++ 2008 (which is C++/CLI - I am told). I want to have a few variables (float x, y, z) in some file "constants.h" which can be accessed by both - the main "Form1.h" (program window) and the properties box "properties.h" (where the user will be able to input values and thus affect the behavior of Form1). The file is called "share variables" so I have the // share variables.cpp : main project file. #include "stdafx.h" #include "constants.h" using namespace sharevariables; // not sure what it does - but need it - it seems #include "properties.h" #include "Form1.h" // constants.h - all the variables here namespace sharevariables { float _cx=3; float _cy=2; // define so I can see they work float _cz=0; } Now the most curious thing - Form1.h has no problem accessing and changing _cx and other variables defined in "constants.h" but "properties.h" gives me an errors: error C2039: '_cx' : is not a member of '`global namespace'' error C2065: '_cx' : undeclared identifier ... :( Please help - I will be able to finally finish my "GravityWars" !!! http://www.yboris.com/gravitywars/gravitywars.html

Share this post


Link to post
Share on other sites
raptorstrike    181
you need to access these variables through the namespace so if your namespace is sharevariables you should access _cx as

sharevariables::_cx

making sure of course that you include the namespace header.

Hope that helps [smile]

Share this post


Link to post
Share on other sites
yboris    122
Quote:
Original post by raptorstrike
...

sharevariables::_cx

...

Hope that helps [smile]


Thank you for the help - but sadly that doesn't work ... if I do what you said then I get the same error as above (though it IS bizarre - as the auto-complete allows me to type in what you said)

If I #include "constants.h" in the "properties.h" I get this:
error C2374: 'sharevariables::_cx' : redefinition; multiple initialization

and if I do the following in my "constants.h"

#ifndef _CONST_
#define _CONST_
namespace sharevariables {
float _cx=3;
float _cy=2;
float _cz=0;
}
#endif

I get an error like this:
share variables.obj : error LNK2005: "float sharevariables::_cz" (?_cz@sharevariables@@$$Q3MA) already defined in properties.obj

It's driving me UP THE WALL! ...

Perhaps someone has played with what I'm doing - and has a simple project that they could just send me - and I can just figure it out ? I'm sure it's supposed to work easily - I'm just not getting something :(

Share this post


Link to post
Share on other sites
raptorstrike    181
hmmm well make sure that the namespace file doesn't include any of the files including it (cyclical inclusion). Here is a minimal example which compiles just fine working on the same principal

main.cpp

#include <iostream>
#include "bar.h"
#include "global_namespace.h" //yes I know its there twice
#include "global_namespace.h"

using namespace std;

int main()
{
bar test;
Foo::_cy = 40;
Foo::_cz = 20;
cout << Foo::_cx << endl;
cout << Foo::_cy << endl;
cout << Foo::_cz << endl;
system("pause");
}






global_namespace.h

#ifndef NAMESPACE_FOO
#define NAMESPACE_FOO

namespace Foo
{
float _cx = 0;
float _cy = 1;
float _cz = 100;
}

#endif






bar.h

#include "global_namespace.h"

class bar
{
public:
bar() { Foo::_cx = 100;}
};




Share this post


Link to post
Share on other sites
yboris    122
Quote:
Original post by raptorstrike
hmmm well make sure that the namespace file doesn't include any of the files including it (cyclical inclusion). Here is a minimal example which compiles just fine working on the same principal...


Thank you for your time and effort, but sadly that code isn't simply (if at all) converted to fit into the Visual C++ 2008 pre-existing code. There is no "main.cpp" (so I tried the best I could to accommodate)

I decided to restart from scratch - built my new code as closely related to what you wrote - and things compile well until the final step - where I let my "properties.h" #include "globals.h" (this time around I called it that).


properties.obj : error LNK2005: "float Foo::_x" (?_x@Foo@@$$Q3MA) already defined in shareforms.obj
C:\Documents and Settings\Boris.MINIPC\My Documents\Visual Studio 2008\Projects\shareforms\Debug\shareforms.exe : fatal error LNK1169: one or more multiply defined symbols found


:( ... if anyone skilled in Visual C++ 2008 Windows Forms has a file they could send me - I'll look and figure it out. Thank you again!

Share this post


Link to post
Share on other sites
Sneftel    1788
raptorstrike's code is incorrect. In the header file, you need to declare the variable as extern:
extern float _cx;

And then, in exactly one .cpp file you put the definition:
float _cx=3;

Also, read this.

Share this post


Link to post
Share on other sites
yboris    122
Quote:
Original post by Sneftel
... you need to declare the variable as extern:
extern float _cx;

And then, in exactly one .cpp file you put the definition:
float _cx=3;

...

Thanks for the speedy suggestion - but sadly this "extern" doesn't fix up my problem. I still get the error I stated above.

Perhaps a quick recap is in order:

I have two forms and "globals.h" that has my variables. The code that compiles well (with Form1 seeing the variables) but as soon as I want my Form2 (properties.h) to "see" the variables - I get the error:


shareforms.obj : error LNK2005: "float Foo::_x" (?_x@Foo@@$$Q3MA) already defined in properties.obj


I am certainly not trying to define the variables - but the program may think it - because I have "properties.h" #include "globals.h" ... and that is where it fails.

Share this post


Link to post
Share on other sites
Sneftel    1788
As I said: You need to put the definition in a separate .cpp file. It cannot be in a header file.
Quote:
I am certainly not trying to define the variables

Well, yes, you are. You need to define the variable, or it doesn't exist. Did you read the article I linked yet?

Share this post


Link to post
Share on other sites
yboris    122
Quote:
Original post by Sneftel
As I said: You need to put the definition in a separate .cpp file. It cannot be in a header file ... Did you read the article I linked yet?


I am a beginner - and I have been told that there is no difference between .cpp or .h - they are just conventions to get you thinking in terms of headers and code ... of course I'm still vague on what either of them are.

I have read the article even before I tried the first time to make the program work, and upon your suggestion looked at it again. I must be missing something - but it seems like it isn't addressing my problem. I think I get roughly the mistakes the article points out I shouldn't be making - and as far as I understand - I am not making them.

I have attempted to create a separate file (floats.cpp) that includes (#include "globals.h") my original definition of variables (with 'extern') and re-defines them "float _x = _cx" within a new namespace "Bar". This compiles well - until I try to get my "properties.h" (Form2) to access the new file.

... thank you again for your time in trying to get it to work ... but I repeat - I'm not programming C++, this is Visual C++ 2008 (.NET 3.5) with its own quirks (syntax) and oddities. I hear C# doesn't even have "global variables" ... I don't know what sort of differences are in this C++/CLI :(

If someone has Visual C++ 2008 - could you share a working - compilable code that does what I'm trying to achieve? I'm willing to pick it apart on my own and figure out how to adapt it to my code. Thank you :)

Share this post


Link to post
Share on other sites
oler1s    585
Quote:
I am a beginner - and I have been told that there is no difference between .cpp or .h - they are just conventions to get you thinking in terms of headers and code ...
It’s a convention to name source files .cpp and header files .h (which compilers are aware of), but there is a clear difference in the role source and header files play. You cannot treat them interchangeably. C++ views source files independently. When you compile a.cpp and b.cpp, there is absolute no way, within your source code, to make them aware of one another. So if you need to use something from a.cpp in b.cpp, like a function or a global variable, you need to declare their existence. Now, you could keep typing out the declarations over and over, but instead, it’s more logical to put them in header files and then include them.

Do you understand why we have header files? Why can’t we just have a bunch of source files? If you can’t answer this question, you cannot organize your code in multiple files properly.

Quote:
I have attempted to create a separate file (floats.cpp) that includes (#include "globals.h") my original definition of variables (with 'extern') and re-defines them "float _x = _cx"
When you use extern, you have a declaration. It’s not a definition, and that’s the point of extern. If you had a definition, it would be in a source file. Then you talk about redefining. You can’t redefine.

Quote:
This compiles well - until I try to get my "properties.h" (Form2) to access the new file.
There is no sane way to interpret this statement. How is a header file, “accessing” a new file?

Quote:
I'm not programming C++, this is Visual C++ 2008 (.NET 3.5) with its own quirks (syntax) and oddities. I hear C# doesn't even have "global variables" ... I don't know what sort of differences are in this C++/CLI :(
This complicates your learning experience. It’s complex enough learning C++, and you’re learning the CLI version. Seriously, if you want to do all the .NET stuff, stick with C#. You’re going to suffer with C++/CLI because you are not familiar with C++ itself.

Share this post


Link to post
Share on other sites
pookemon    100
Quote:
Original post by yboris
I hear C# doesn't even have "global variables" ...


Yes it does - they are implemented via a "Static Class".

You need to read through what oler1s and Sneftel have written. Essentially you should have a header that contains the extern declarations and then the definition should be in one of your source files.

constants.h

#ifndef __constants_h__
#define __constants_h__

extern float _cx;
extern float _cy;
extern float _cz;

#endif



constants.cpp

float _cx = 0.0f;
float _cy = 0.0f;
float _cz = 0.0f;



Form1.cpp

#include "constants.h"

class Form1
{
public:
Form1()
{
_cx = 0.0f;
};
}



Form2.cpp

#include "constants.h"

class Form2
{
public:
Form2()
{
_cy = 0.0f;
};
}



Or something like that...

Share this post


Link to post
Share on other sites
yboris    122
Quote:
...You need to read through what oler1s and Sneftel have written...

Thank you very much, between you and everyone who contributed - I finally managed to get the damn 'extern' to work without complaining ... and a little bit after ...

ZOMG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! :D

THANK YOU - IT WORKS !!!

I love you all forever. Visit
http://www.yboris.com/gravitywars/gravitywars.html
to download a working implementation (with properties) of my game :)

[Edited by - yboris on June 11, 2008 1:00:50 AM]

Share this post


Link to post
Share on other sites
yboris    122
MASSIVE THANK YOU

Thank you all for your contributions. My website is now up and I listed you as contributors to my program.

http://gravitywars.yboris.com

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