Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

static void methods/functions and passing data

Status
Not open for further replies.

TheObserver

Programmer
Mar 26, 2002
91
US
I'm working in C++, C, and XWindows.

I am having a problem where I need to call a class, set an object pointer to point at an object I passed in with the constructor's argument list, and then when I do a callback in response to a GUI item being clicked (XWindows stuff), I pass the pointer back to a C function so it can act on the object and have everything be groovy.

My problem lies in that for some reason the method I call from my callback has to be a static void. As such, I can't pass in the pointer to the object that I need to pass along to the C function. I have tried not using static void, but the compiler chokes and says I don't have a method defined as void(*)(parameter list) - it's defined as void (parameter list).

So, either I can have a method that works, but doesn't do anything useful (it cores), or I have a method that would seemingly do what I need it to (gets the pointer and passes it along to the C function) except that it won't compile.

Any info/ideas/leads?

Thanks for your time.
 
> call a class

That doesn't mean anything. You probably mean call a class's constructor.


So, usually, for callback-type stuff in C, the callback-registering function accepts a void* argument to be passed to the callback function when the call occurs. Put the pointer to the object in there, then cast it back in your callback before using it.
 
Could you explain what you mean by "then cast it back in your callback before using it"? I'm just trying to get the function that the callback references working. I'm not really doing anything in regard to the XWindows callback at all, other than using it to connect the GUI item to the C function I'm trying to use.

The functions seem to need to be defined with XWindows' standard (widget, xtpointer, xtpointer) arg list, but I can call them (functions) without those arguments being passed along. However, if I add the pointer to the list, it gives me the compile error of the function not being static void (essentially). If I remove the pointer arg, change the function to static void, and try to use a global var set to the object pointer, I get the no void(*)(*,*,*) compiler error.

I need a way to get the pointer to the object I'm passing in into this function without it having to be set to static void. I don't think the functions in question would know how to use anything passed as (*)(*,*,*) when they are currently set as (*,*,*) for their arg list (and this is legacy code, so I can't modify it).

If this response is as clear to mud, I've only been doing XWindows for a couple of days and what I'm working on doesn't seem to be anything like the examples you'd typically find in an "intro to..." type resource.
 
> Could you explain what you mean by "then cast it back in your callback before using it"?

According to what you said about the argument list, this doesn't really apply anymore, I guess. I was just saying that normally, when you register a callback, you do something like:

Code:
register_callback( &my_func, &some_object )

The second argument is of type [tt]void*[/tt], so it's just an address into memory. This is done so you can pass anything you want to the function to be called, so the same generic callback interface can be used to register functions that work with ints, doubles, struct foos, etc.

Your my_func would have a signature that accepts a void* argument.

When the callback occurs, it passes the object you registered to the callback function. Effectively:

Code:
my_func( some_object );

At that point, my_func gets a [tt]void*[/tt]. my_func knows what type that pointer is supposed to point to (a double, for example). So before my_func can use the argument passed to it, it needs to cast it from [tt]void*[/tt] to the type it's expected to be.
 
With X windows, it is a signature problem. Most of the callbacks are of type
Code:
void callback(void*)
With classes, the problem is that they have to be object based. That is why you need
Code:
static ClassType::callback (void* self)
On some compilers, yo might even have to have two levels because the signature is extern "C". What you'd normally do in the callback is
Code:
ClassType* self = (ClassType*) selfptr;
If you wish to pass more than a class, then you could do one of two things. One option is to set a member in the class before invoking the callback. The callback can then examine the member variable. The other is to pass a structure in with a pointer to the class and any other parameters you wish to set. In the callback, just cast back to the structure and you're done.
 
I suggest you use an Object-Oriented GUI framework. XWindows is pretty hard to learn and use. There are free and really well-designed OO frameworks nowadays.
One I'm daily using is Qt from TrollTech, if you don't know it you could give a try.
Moreover, the X11 version is free(thought you must use it for non-commercial projects) :

It comes also with a really good documentation and some tutorials.

--
Globos
 
Alternatively, you could use Motif++. The big problem with Motif and C++ is the destructors and it is not just one clean interface. You still need to delve into X11 sometimes.

QT is nice: it is also portable to Windows. However, if you are playing with legacy stuff, you're probably stuck with X11/XMotif/XView.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top