472,958 Members | 2,578 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,958 software developers and data experts.

Passing member functions to C functions?

I am trying to convert some basic OpenGL code to an OO form. This is the C
version of the program:

http://www.opengl.org/resources/code...dbook/double.c

You can see what my current effort at converting that code to an OO form
looks like in the code listed below. The problem I'm running into is that
the OpenGL functions that take the names of other functions as arguments
don't like the way I'm passing the member functions of my class. I started
out making all member functions non-static, but couldn't figure out a way
to pass them to functions such as glutDisplayFunc(&GlutMain::display);

Is there a way to accomplish this?

#ifndef GLUTMAIN_HH
#define GLUTMAIN_HH

#include <GL/glut.h>
namespace sth {
namespace vmathGL {
class GlutMain {
public:

GlutMain(int argc, char* argv[]);

virtual ~GlutMain();

void run();

static void init();

static void display();

static void reshape(int w, int h);

static void mouse(int button, int state, int x, int y);

static void key(unsigned char k, int x, int y);

static void spinDisplay();
private:
static GLfloat _spin;
};
}
}
#endif

#include "GlutMain.hh"

#include <cstdlib>

namespace sth {
namespace vmathGL {
GlutMain::GlutMain(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(250,250);

}

GlutMain::~GlutMain()
{

}

void GlutMain::run()
{
init();
glutDisplayFunc(&GlutMain::display); // compiles but segfaults.

/*
glutReshapeFunc(&reshape);
glutMouseFunc(&mouse);
glutMainLoop();
*/
}

void GlutMain::display()
{
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glRotatef(_spin, 0.0, 0.0, 1.0);
glColor3f(1.0, 1.0, 1.0);
glRectf(-25.0, -25.0, 25.0, 25.0);
glPopMatrix();
glutSwapBuffers();
}

void GlutMain::init()
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
}

void GlutMain::reshape(int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void GlutMain::mouse(int button, int state, int x, int y)
{
switch (button) {
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(spinDisplay);
break;
case GLUT_MIDDLE_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(NULL);
break;
default:
break;
}
}

void GlutMain::key(unsigned char k, int x, int y)
{
switch (k) {
case 27: /* Escape */
exit(0);
break;
default:
return;
}
glutPostRedisplay();
}

void GlutMain::spinDisplay()
{
_spin = _spin + 2.0;
if (_spin > 360.0)
_spin = _spin - 360.0;
glutPostRedisplay();
}

GLfloat GlutMain::_spin = 0.0;

}
}

--
"If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true." - Bertrand
Russell

Jul 22 '05 #1
7 2432
"Steven T. Hatton" <su******@setidava.kushan.aa> wrote in message
news:jN********************@speakeasy.net...
I am trying to convert some basic OpenGL code to an OO form. This is the C version of the program:

http://www.opengl.org/resources/code...dbook/double.c

You can see what my current effort at converting that code to an OO form
looks like in the code listed below. The problem I'm running into is that
the OpenGL functions that take the names of other functions as arguments
don't like the way I'm passing the member functions of my class. I started out making all member functions non-static, but couldn't figure out a way
to pass them to functions such as glutDisplayFunc(&GlutMain::display);

Is there a way to accomplish this?

<snip>

Well, you can't pass non-static member functions as a C callback. To invoke
a non-static member function, you need an object, and C simply doesn't know
how to invoke members on an object. The FAQ discusses this in 33.1, 2, and
3.

I think you might want to take a peek at the GlutMaster implementation
(http://www.duke.edu/~stetten/GlutMas...utMaster.html). It apparently
uses the "window id" as a key for the corresponding callback object, so you
could probably do something similar.

--
David Hilsee
Jul 22 '05 #2
> [...]
Well, you can't pass non-static member functions as a C callback. To invoke
a non-static member function, you need an object, and C simply doesn't know
how to invoke members on an object. [...]


http://parashift.com/c%2B%2B-faq-lit....html#faq-33.2

Can function objects/functors also be used for the requested application?
http://en.wikipedia.org/wiki/Function_object
Jul 22 '05 #3
"Markus Elfring" <Ma************@web.de> wrote in message
news:40**************************@posting.google.c om...
[...]
Well, you can't pass non-static member functions as a C callback. To invoke a non-static member function, you need an object, and C simply doesn't know how to invoke members on an object. [...]


http://parashift.com/c%2B%2B-faq-lit....html#faq-33.2

Can function objects/functors also be used for the requested application?
http://en.wikipedia.org/wiki/Function_object


If a library asks for a function pointer as a callback, then, no, you can't
pass it a functor. C libraries often require function pointers and have no
understanding of operator overloading, member functions, etc. The wikipedia
entry is a little misleading because it doesn't mention that the sort
function in the C example and the sort function in the C++ example are
actually two different functions. It should have a declaration of sort() in
each example.

--
David Hilsee
Jul 22 '05 #4
> > http://parashift.com/c%2B%2B-faq-lit....html#faq-33.2

Can function objects/functors also be used for the requested application?
http://en.wikipedia.org/wiki/Function_object


If a library asks for a function pointer as a callback, then, no, you can't
pass it a functor. C libraries often require function pointers and have no
understanding of operator overloading, member functions, etc. The wikipedia
entry is a little misleading because it doesn't mention that the sort
function in the C example and the sort function in the C++ example are
actually two different functions. It should have a declaration of sort() in
each example.


Would you like to improve the article?

Are the descriptions about "functionoids" relevant here?
http://parashift.com/c%2B%2B-faq-lit...html#faq-33.10
Jul 22 '05 #5
David Hilsee wrote:
Well, you can't pass non-static member functions as a C callback. To
invoke a non-static member function, you need an object, and C simply
doesn't know how to invoke members on an object. The FAQ discusses this in
33.1, 2, and 3.


Oh my! I got FAQed. For shame! ;)

I actually had some problems with using static members as well, but don't
recall the details. What I ended up doing was to create a global <blush>
GlutMain* gmPtr and instantiating a corresponding object at the top of
main(). Additionally, I replaced the bodies of the corresponding C
functions with calls to gmPtr->functionName(/*args...*/). In the case where
I had to deal with function pointers, I did this:

void GlutMain::mouse(int button, int state, int x, int y, void(*spinDisp)())
{
switch (button) {
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(spinDisp);
break;
case GLUT_MIDDLE_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(NULL);
break;
default:
break;
}
}

My CVS server had a HD crash last week, so (alack and alas) I have not been
keeping snapshots. I therefore don't have the corresponding version of
spinDisp, but it was very similar to

void spinDisp()
{
gmPtr->spinDisplay();
}

So I pass as an argument to a C++ member function, a pointer to a C
(compatable under current conditions) function that invokes a C++ member
function on the same object. The main() I ended up with looked very similar
to the original redbook example with the addition of the object creation.

How's /that/ for elegant simplicity? :D
--
"If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true." - Bertrand
Russell

Jul 22 '05 #6
"Markus Elfring" <Ma************@web.de> wrote in message
news:40**************************@posting.google.c om...
http://parashift.com/c%2B%2B-faq-lit....html#faq-33.2
Can function objects/functors also be used for the requested application? http://en.wikipedia.org/wiki/Function_object


If a library asks for a function pointer as a callback, then, no, you can't pass it a functor. C libraries often require function pointers and have no understanding of operator overloading, member functions, etc. The wikipedia entry is a little misleading because it doesn't mention that the sort
function in the C example and the sort function in the C++ example are
actually two different functions. It should have a declaration of sort() in each example.


Would you like to improve the article?

Are the descriptions about "functionoids" relevant here?
http://parashift.com/c%2B%2B-faq-lit...html#faq-33.10


I added a few extra lines to the example to clarify. The functionoid is
certainly relevant. The C++ example's actually pretty worthless because
there is no way to supply something that implements the comparison function
differently. Perhaps that should be the next enhancement (polymorphism or
templates).

--
David Hilsee
Jul 22 '05 #7
"Steven T. Hatton" <su******@setidava.kushan.aa> wrote in message
news:O6********************@speakeasy.net...
David Hilsee wrote:
Well, you can't pass non-static member functions as a C callback. To
invoke a non-static member function, you need an object, and C simply
doesn't know how to invoke members on an object. The FAQ discusses this in 33.1, 2, and 3.
Oh my! I got FAQed. For shame! ;)


Ah, there's no shame in being FAQed. I FAQ everyone. (Better make sure I
pronounce that correctly)
I actually had some problems with using static members as well, but don't
recall the details. What I ended up doing was to create a global <blush>
GlutMain* gmPtr and instantiating a corresponding object at the top of
main(). Additionally, I replaced the bodies of the corresponding C
functions with calls to gmPtr->functionName(/*args...*/). In the case where I had to deal with function pointers, I did this:

void GlutMain::mouse(int button, int state, int x, int y, void(*spinDisp)()) {
switch (button) {
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(spinDisp);
break;
case GLUT_MIDDLE_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(NULL);
break;
default:
break;
}
}

My CVS server had a HD crash last week, so (alack and alas) I have not been keeping snapshots. I therefore don't have the corresponding version of
spinDisp, but it was very similar to

void spinDisp()
{
gmPtr->spinDisplay();
}

So I pass as an argument to a C++ member function, a pointer to a C
(compatable under current conditions) function that invokes a C++ member
function on the same object. The main() I ended up with looked very similar to the original redbook example with the addition of the object creation.

How's /that/ for elegant simplicity? :D


That works. GlutMaster's approach replaced your global with a table, which
is a little better, but in the end, it's about the same, really. I'm
somewhat surprised that the library didn't allow you to register a void* and
a function pointer. That's a common practice that is very friendly to C++
applications.

--
David Hilsee
Jul 22 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Newsgroup - Ann | last post by:
Gurus, I have the following implementation of a member function: class A { // ... virtual double func(double v); void caller(int i, int j, double (* callee)(double)); void foo() {caller(1,...
2
by: Anthony | last post by:
Hi, I want to write protect an argument that is passed by reference. But I still want to be able to call members of that argument. E.g. code (bottum) will gives the following compiler error:...
2
by: dave.harper | last post by:
I'm relatively new to C++, but have a question regarding functions and arrays. I'm passing a relatively large array to a function several thousand times during the course of a loop, and it seems...
11
by: cps | last post by:
Hi, I'm a C programmer taking my first steps into the world of C++. I'm currently developing a C++ 3D graphics application using GLUT (OpenGL Utility Toolkit written in C) for the GUI...
32
by: paul | last post by:
HI! I keep on getting this error and I have tried different things but I am not sure how to send the expiring date. The error that I am getting in Firefox 1.5 is "Error: expires.toGMTString is...
3
by: dice | last post by:
Hi, In order to use an external api call that requires a function pointer I am currently creating static wrappers to call my objects functions. I want to re-jig this so I only need 1 static...
18
by: tbringley | last post by:
I am a c++ newbie, so please excuse the ignorance of this question. I am interested in a way of having a class call a general member function of another class. Specifically, I am trying to...
8
by: S. | last post by:
Hi all, Can someone please help me with this? I have the following struct: typedef struct { char *name; int age; } Student;
8
by: Ruben | last post by:
error: passing `const Weight' as `this' argument of `float Weight::wgt()' discards qualifiers seems to be some sort of standard error format that I'm not understanding. I have code that...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
4
NeoPa
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
2
by: GKJR | last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.