Callback to a non-static method?

L

Levin Alexander

Hi,

(I hope that this is not a FAQ)

I'm trying to make a timer call a method of an object.

void MyClass::myCallback(int par)
{cout << "Callback Called" << std::endl;}

void MyClass::addTimer()
{
signal(SIGALRM, myCallback);
// ...
}

This does not work. The Error is
"argument of type 'void (MyClass::)(int)' does not match 'void (*)(int)'"

Why is that not working? Is there a workaround?

Thanks,
Levin
 
A

Alf P. Steinbach

* "Levin Alexander said:
I'm trying to make a timer call a method of an object.

void MyClass::myCallback(int par)
{cout << "Callback Called" << std::endl;}

void MyClass::addTimer()
{
signal(SIGALRM, myCallback);
// ...
}

This does not work. The Error is
"argument of type 'void (MyClass::)(int)' does not match 'void (*)(int)'"

Be glad you got a compilation error, because mixing C signals and C++
object-oriented code is simply not supported, and leads to UB.

So the technical error prevented you from making a much more serious
and much more difficult to pin down error.

Many others will probably explain how to do The Technical Thing (TM)
to get the code to compile (thus introducing the Grave Error (TM)).
 
L

Levin Alexander

Alf P. Steinbach said:
Be glad you got a compilation error, because mixing C signals and C++
object-oriented code is simply not supported, and leads to UB.

(I sense the need to buy a decent book.)

Is there a "pure" C++ way to solve that problem?

Thanks,
Levin
 
A

Alf P. Steinbach

* "Levin Alexander said:
(I sense the need to buy a decent book.)

Is there a "pure" C++ way to solve that problem?

Not "pure", but by using platform-specific functionality you can implement
timers that are, for example, exception safe.
 
A

Allan Bruce

Levin Alexander said:
Hi,

(I hope that this is not a FAQ)

I'm trying to make a timer call a method of an object.

void MyClass::myCallback(int par)
{cout << "Callback Called" << std::endl;}

void MyClass::addTimer()
{
signal(SIGALRM, myCallback);
// ...
}

This does not work. The Error is
"argument of type 'void (MyClass::)(int)' does not match 'void (*)(int)'"

Why is that not working? Is there a workaround?

Thanks,
Levin

You could have one static member which takes a pointer to the type of class
it belongs, then you could pass it the 'this' pointer.

e.g.

void MyClass::Callback(MyClass *xiThis, ...)
{
xiThis->NonStaticCallback(...);
}

HTH
Allan
 
A

Alf P. Steinbach

* "Allan Bruce said:
You could have one static member which takes a pointer to the type of class
it belongs, then you could pass it the 'this' pointer.

e.g.

void MyClass::Callback(MyClass *xiThis, ...)
{
xiThis->NonStaticCallback(...);
}

Although the above will work with all relevant compilers (AFAIK), it's
officially ungood. A C callback needs to be 'extern "C"'. Hence
it needs to be a namespace scope function.
 
D

DaKoadMunky

Many others will probably explain how to do The Technical Thing (TM)
to get the code to compile (thus introducing the Grave Error (TM)).

Could you explain further please?

What is The Technical Thing?

What is The Grave Error?


Brian F. Seaberg
Naperville, Illinois
Delray Beach, Florida
 
A

Alf P. Steinbach

* (e-mail address removed) (DaKoadMunky) schriebt:
Could you explain further please?

What is The Technical Thing?

Explained by others in this thread, as predicted.

What is The Grave Error?

All explained by the part you snipped,

Be glad you got a compilation error, because mixing C signals and C++
object-oriented code is simply not supported, and leads to UB.

C signals are asynchronous, meaning a signal can occur at any point in
the machine code execution, for example at a point where the global
data structures, including structures related to e.g. exception handling
and maintained by compiler-inserted code, are not in well-defined states.

That means that there's really very little you can safely do in a signal
handler except set some global POD flags or terminate the process.

For example, i/o via the standard library is in general not a good idea.

And in particular, it's absolutely not a good idea to propagate an
exception out of a signal handler, and it may (but just may) be disastrous
to have any kind of exception handling inside it, which precludes use of
most of the standard library.

Also, signal handlers are traditionally associated with use of longjmp,
which isn't supported in C++ code; e.g. you're not guaranteed that stack
based objects will be properly destroyed (have their destructors called).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,164
Messages
2,570,898
Members
47,439
Latest member
shasuze

Latest Threads

Top