CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Jun 2007
    Location
    Vercelli, Italy
    Posts
    87

    C++ and global objects

    Hi everyone! Here I am again with my best wishes of a happy new year to all the Codeguru people... and with a new happy problem for everyone! :-D

    I'm using the GLUT (GL Utility Toolkit, for those who don't know about it) to develop a graphic application. The problem lies not in the graphic API nor in any matter related to graphics. The thing is, GLUT uses an approach based on callbacks: for each window a callback function is used for display, keyboard or mouse events, idle time, and all the stuff.

    This kind of architecture is what makes it hard for me to use GLUT with C++. The problems I've encountered are basically two:

    1) since the right thing to do would be to enclose most of the code inside of a class (including a singleton object of an Application class), I still need to specify a pointer to the function to be used as a callback, and this function should be a member function, which is hard to do (I found a couple of techniques, but I can't convince myself that they're worth the pain);

    2) the usual approach I used in C was to create a "global" header file, which I would include in the main, and which would declare all the global variables (for example, the data structure that will contain the map of the world, since it will have to be available in multiple callback functions). Now, if I declare some objects this way (say, in "mainlib.h") and then include the header in more than one source file, the linker says that the object had already been declared in another object file.

    Is there an easy way to overcome the limitations and the difficulties of such an architecture using C++?
    I owe Paul McKenzie a pizza.

    I am no expert; but they say I can make concepts easy to understand. That's why newbies questions are mine!!! XD

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: C++ and global objects

    Quote Originally Posted by Sk#
    1) since the right thing to do would be to enclose most of the code inside of a class (including a singleton object of an Application class), I still need to specify a pointer to the function to be used as a callback, and this function should be a member function, which is hard to do (I found a couple of techniques, but I can't convince myself that they're worth the pain);
    Can you show us what you did? I do not know GLUT, so I'm surmising that the callback function must be a static member function if it is to be used within a class.

    The way this is usually done if the function must be static is that the static function finds the object that the callback is associated with, and then calls the object's Paint, Keyboard, whatever function. These other functions are non-static members. The way that the callback searches for the correct object -- there are many ways that it could do it.
    2) the usual approach I used in C was to create a "global" header file, which I would include in the main, and which would declare all the global variables (for example, the data structure that will contain the map of the world, since it will have to be available in multiple callback functions). Now, if I declare some objects this way (say, in "mainlib.h") and then include the header in more than one source file, the linker says that the object had already been declared in another object file.
    That is because for global variables that are shared across source units, only one source unit declares the variable, and the other source units must use the extern keyword.

    But there is no need for globals. This is not the best thing, but as a start, just put those globals in a class as static members. Then you can include that class in as many places as you want and not have any linker errors. Of course, you have to change your source code to say "MyGlobals::whatever" instead of "whatever", since they are all static members of a class.

    Regards,

    Paul McKenzie

  3. #3
    Join Date
    Jun 2007
    Location
    Vercelli, Italy
    Posts
    87

    Re: C++ and global objects

    It's not either a structure that revolves around static functions. This is what a typical GLUT program would look like (pure C):
    Code:
    #include <GL/glut.h>
    #include <stdlib.h>
    
    void display(void)
    {
    	glClearColor(0, 0, 0, 1);
    	glClear(GL_COLOR_BUFFER_BIT);
    
    	glutSolidSphere(30, 30, 30); // draws a sphere centered in the origin
    
    	glutSwapBuffers();
    }
    
    void keybd(unsigned char key, int x, int y)
    {
    	if (key == 27)
    		exit(0); // quits on ESC
    }
    
    int main(int argc, char **argv)
    {
    	glutInit(&argc, argv);
    	// other GLUT initialization calls
    
    	glutCreateWindow("Window Title"); 
    	// callbacks for the newly created window
    	glutDisplayFunc(display); // draws the frame in the back buffer
    	glutKeyboardFunc(keybd); // handles keyboard events
    
    	glutMainLoop(); // the main loop; it calls the functions registered above
    }
    In pure C it was easy to declare the functions in a header file and to define them in different source files. Besides, imagine a double v that stores the speed of a ball moving across the screen; it needs to be available in both display and keybd (for example, the user might accelerate the ball with the space bar and slow it down with another key); then the variable could be declared in a header (using of course the extern keyword as appropriate), and used across several source files.

    With objects the extern keyword isn't enough. If I declare
    Code:
    Camera mainCamera(0, 0, 0);
    in the "global" header file, still I get link errors ("class Camera mainCamera already defined in...").

    The best thing would probably be what follows (neglecting all that makes it singleton, just a quick demonstration of the concept):
    Code:
    #include <GL/glut.h>
    
    class Application
    {
    public:
    	void Run()
    	{
    		glutCreateWindow("Window Title");
    		glutDisplayFunc(display);
    		glutMainLoop();
    	}
    private: // ???
    	void display(void)
    	{
    		// display code
    	}
    };
    
    int main(int argc, char **argv)
    {
    	// GLUT initialization
    
    	Application app;
    	app.Run();
    }
    This would preserve the principles of OOP, and would allow me to declare any of what were once global variables (the speed of the ball) as member variables of the Application class. I couldn't find a way to let the GLUT accept a member function (nor a static function, at that) as the callback routine. I don't think this is a GLUT-related problem; I probably need to know an easy way to specify a class function as a callback.
    I owe Paul McKenzie a pizza.

    I am no expert; but they say I can make concepts easy to understand. That's why newbies questions are mine!!! XD

  4. #4
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588

    Re: C++ and global objects

    Have you checked out Glow? It's a C++ binding for GLUT supposedly.

    On your question, you cannot specify non-static member functions as callbacks for GLUT because it expects the functions to be C-style functions. A member function actually always has a hidden this parameter which is a pointer to the current object. Since glut doesn't provide that parameter, you cannot use it that way. As Paul said, there are a number of ways around this, but it can become slightly involved.

    For the Camera mainCamera(0, 0, 0); linker problem, you can't declare a variable many times, it will indeed result in a linker problem. Since you include the header file in multiple cpp files, it will be declared multiple times. A solution is to declare it as:
    Code:
    // global.h
    extern Camera mainCamera;
    // ONE cpp file (maybe call it globals.cpp)
    Camera mainCamera(0, 0, 0);
    Get this small utility to do basic syntax highlighting in vBulletin forums (like Codeguru) easily.
    Supports C++ and VB out of the box, but can be configured for other languages.

  5. #5
    Join Date
    Jun 2007
    Location
    Vercelli, Italy
    Posts
    87

    Re: C++ and global objects

    Thanks Yves! I've checked GLOW out, but couldn't get it to compile (MS VS05). Instead, I tried again and found out that my previous experiments were flawed: one *can* wrap the GLUT in C++, using static member functions as callbacks and static data members as "global objects" (declared inside the class, defined in exactly one object file). In general, a static member function can be used as a callback function pointer, since it requires no this pointer. I'm following this architecture now. Thanks anyone for their suggestions!
    I owe Paul McKenzie a pizza.

    I am no expert; but they say I can make concepts easy to understand. That's why newbies questions are mine!!! XD

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured