Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Error passing function in signal( ... )

Reply
Thread Tools

Error passing function in signal( ... )

 
 
Dudebot
Guest
Posts: n/a
 
      12-29-2010
Hi Gurus, I'm porting some C code into a C++ environment. I have
working signal code in C:

#includes for signal...

static void exit_gracefully()
{
*control = STOP|TWSIEN; // send stop signal
exit( 0 );
}

int main( int argc, char **argv )
{
....
signal( SIGTERM, exit_gracefully );

However, when I try to port it into a class, e.g.

class ADC {
public:
....
void sample(); // sample ADC

private:
volatile unsigned int *control;
void exit_gracefully();
};

void ADC::exit_gracefully()
{
*control = STOP|TWSIEN; // send stop signal
exit( 0 );
}

void ADC::sample()
{
....
signal( SIGTERM, exit_gracefully );

I get these compilation errors:

error: argument of type `void (ADC:()' does not match `void
(*)(int)'

I can't pull exit_gracefully() out of the class, as it needs to access
the private member control.

I tried casting the function in the signal call
signal( SIGTERM, void (*)(int) exit_gracefully );

But I'm getting
error: parse error before `)' token

I tried all sorts of typedef conconctions a la
http://www.parashift.com/c++-faq-lit....html#faq-33.5,
but can't get anything to help.

Any ideas?

Many TIA,
Craig
 
Reply With Quote
 
 
 
 
Pavel Borzenkov
Guest
Posts: n/a
 
      12-29-2010
On 2010-12-29, Dudebot <(E-Mail Removed)> wrote:
> Hi Gurus, I'm porting some C code into a C++ environment. I have
> working signal code in C:
>
> #includes for signal...
>
> static void exit_gracefully()
> {
> *control = STOP|TWSIEN; // send stop signal
> exit( 0 );
> }
>
> int main( int argc, char **argv )
> {
> ...
> signal( SIGTERM, exit_gracefully );
>
> However, when I try to port it into a class, e.g.
>
> class ADC {
> public:
> ...
> void sample(); // sample ADC
>
> private:
> volatile unsigned int *control;
> void exit_gracefully();
> };
>
> void ADC::exit_gracefully()
> {
> *control = STOP|TWSIEN; // send stop signal
> exit( 0 );
> }
>
> void ADC::sample()
> {
> ...
> signal( SIGTERM, exit_gracefully );
>
> I get these compilation errors:
>
> error: argument of type `void (ADC:()' does not match `void
> (*)(int)'
>


Yes. They have different types.

> I can't pull exit_gracefully() out of the class, as it needs to access
> the private member control.


You could implement get/set methods for this variable.
Another way is to declare the exit_gracefully function as static,
so its type will be "void (*)(int)"

>
> I tried casting the function in the signal call
> signal( SIGTERM, void (*)(int) exit_gracefully );
>
> But I'm getting
> error: parse error before `)' token
>
> I tried all sorts of typedef conconctions a la
> http://www.parashift.com/c++-faq-lit....html#faq-33.5,
> but can't get anything to help.


You used the wrong link. See point 33.2 in the same FAQ.

>
> Any ideas?
>
> Many TIA,
> Craig

 
Reply With Quote
 
 
 
 
Ian Collins
Guest
Posts: n/a
 
      12-29-2010
On 12/30/10 11:39 AM, Dudebot wrote:
> Hi Gurus, I'm porting some C code into a C++ environment. I have
> working signal code in C:


<snip>


> I get these compilation errors:
>
> error: argument of type `void (ADC:()' does not match `void
> (*)(int)'


That's correct, the function signatures don't match.

> I can't pull exit_gracefully() out of the class, as it needs to access
> the private member control.


Then declare it extern "C" and make it a friend of the class.

--
Ian Collins
 
Reply With Quote
 
Dudebot
Guest
Posts: n/a
 
      12-29-2010
Whoa. This seems like choosing between two bad design options, almost
a philosophical question.

Pavel points me to making a wrapper in
http://www.parashift.com/c++-faq-lit....html#faq-33.2,
where the number of caveats is too numerous to count

Ian tells me to make it extern... meaning, try to match the objects
perfectly in the compile, and hope for the best.

Are these really the only two good ways to proceed?

(Thanks, Pavel and Ian!)

Craig
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      12-30-2010
On 12/30/10 12:48 PM, Dudebot wrote:
> Whoa. This seems like choosing between two bad design options, almost
> a philosophical question.
>
> Pavel points me to making a wrapper in
> http://www.parashift.com/c++-faq-lit....html#faq-33.2,
> where the number of caveats is too numerous to count
>
> Ian tells me to make it extern... meaning, try to match the objects
> perfectly in the compile, and hope for the best.


Hope for the best?

> Are these really the only two good ways to proceed?


Well your options are limited by the C interface you are working with.
You simply can't pass a C++ member function (the signature is wrong)
some compilers will let you get away with a static member function , but
the linkage is still wrong.

The handler function signature means neither a static member or a friend
function can be passed a pointer to a class instance. Using the int
parameter to pass some form of index might be your only option.

--
Ian Collins
 
Reply With Quote
 
Jorgen Grahn
Guest
Posts: n/a
 
      12-30-2010
On Wed, 2010-12-29, Dudebot wrote:
> Hi Gurus, I'm porting some C code into a C++ environment. I have
> working signal code in C:
>
> #includes for signal...
>
> static void exit_gracefully()
> {
> *control = STOP|TWSIEN; // send stop signal
> exit( 0 );
> }


That's not really a "graceful" exit in C++ -- your destructors won't
run. May or may not matter to your application, of course ...

The simple workaround is to throw an exception instead and catch it
in main().

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
 
Reply With Quote
 
Richard Kettlewell
Guest
Posts: n/a
 
      12-30-2010
Jorgen Grahn <(E-Mail Removed)> writes:
> Dudebot wrote:


>> Hi Gurus, I'm porting some C code into a C++ environment. I have
>> working signal code in C:
>>
>> #includes for signal...
>>
>> static void exit_gracefully()
>> {
>> *control = STOP|TWSIEN; // send stop signal
>> exit( 0 );
>> }

>
> That's not really a "graceful" exit in C++ -- your destructors won't
> run. May or may not matter to your application, of course ...


Destructors of static-duration objects are called by exit(). BUT they
are almost certainly not safe to run in the context of a signal
handler (almost nothing is).

(For that matter C99 doesn't even allow exit() - only _Exit().)

> The simple workaround is to throw an exception instead and catch it
> in main().


Throwing an exception from a signal handler sounds like a very bad plan
indeed.

--
http://www.greenend.org.uk/rjk/
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      12-30-2010
On Dec 30, 2:17 am, Ian Collins <(E-Mail Removed)> wrote:
> On 12/30/10 12:48 PM, Dudebot wrote:


> > Whoa. This seems like choosing between two bad design options, almost
> > a philosophical question.


> > Pavel points me to making a wrapper in
> >http://www.parashift.com/c++-faq-lit....html#faq-33.2,
> > where the number of caveats is too numerous to count


> > Ian tells me to make it extern... meaning, try to match the objects
> > perfectly in the compile, and hope for the best.


> Hope for the best?


> > Are these really the only two good ways to proceed?


> Well your options are limited by the C interface you are working with.
> You simply can't pass a C++ member function (the signature is wrong)
> some compilers will let you get away with a static member function , but
> the linkage is still wrong.


> The handler function signature means neither a static member or a friend
> function can be passed a pointer to a class instance. Using the int
> parameter to pass some form of index might be your only option.


It's not really an option either; you're very, very limited with
regards to what you can do in a signal handler: you *can't* call
exit (which he apparently wants to do), you can't even access
anything C++. According to the C standard, all you can do is
write (but not read) to a variable with type sig_atomic_t.
Posix (and presumably Windows) allows a little bit more, but
nothing which involves C++: you can't do stream IO (FILE* or
iostream), you can't call a destructor, and you can't throw an
exception. (You can call _exit or abort, but this won't flush
any stream buffers.)

More generally, you probably don't want to, at least if the goal
is to trigger a clean shutdown. You normally can't start
a clean shutdown at just anytime, and signals arrive
asynchronously. The usual solution depends on the application:
for anything multithreaded under Unix, you can create a special
signal handler thread; signals will generate an event which
unblocks the thread, and the thread can start the clean shutdown
(running as a normal thread, and not as a signal handler). For
single threaded processes, the usual solution is just to have
a global sig_atomic_t initialized to zero, set it to one in the
signal handler, and poll it at appropriate moments.

--
James Kanze
 
Reply With Quote
 
Jorgen Grahn
Guest
Posts: n/a
 
      12-30-2010
On Thu, 2010-12-30, Richard Kettlewell wrote:
> Jorgen Grahn <(E-Mail Removed)> writes:
>> Dudebot wrote:

>
>>> Hi Gurus, I'm porting some C code into a C++ environment. I have
>>> working signal code in C:
>>>
>>> #includes for signal...
>>>
>>> static void exit_gracefully()
>>> {
>>> *control = STOP|TWSIEN; // send stop signal
>>> exit( 0 );
>>> }

>>
>> That's not really a "graceful" exit in C++ -- your destructors won't
>> run. May or may not matter to your application, of course ...

>
> Destructors of static-duration objects are called by exit().


Ok, but the other ones (the vast majority of all objects) are not
destroyed properly.

> BUT they
> are almost certainly not safe to run in the context of a signal
> handler (almost nothing is).
>
> (For that matter C99 doesn't even allow exit() - only _Exit().)
>
>> The simple workaround is to throw an exception instead and catch it
>> in main().


Sorry, didn't spot that he used actual signals. The comment about
"send stop signal" in the actual signal handler confused me -- I
thought he just used the word "signal" for his own purposes.

> Throwing an exception from a signal handler sounds like a very bad plan
> indeed.


Agreed.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
 
Reply With Quote
 
Dudebot
Guest
Posts: n/a
 
      12-30-2010
On Dec 30, 5:33*am, James Kanze <(E-Mail Removed)> wrote:

> More generally, you probably don't want to, at least if the goal
> is to trigger a clean shutdown. *You normally can't start
> a clean shutdown at just anytime, and signals arrive
> asynchronously. *The usual solution depends on the application:
> for anything multithreaded under Unix, you can create a special
> signal handler thread; signals will generate an event which
> unblocks the thread, and the thread can start the clean shutdown
> (running as a normal thread, and not as a signal handler). *For
> single threaded processes, the usual solution is just to have
> a global sig_atomic_t initialized to zero, set it to one in the
> signal handler, and poll it at appropriate moments.


Wow, I learned a lot from this thread--many thanks, all. James, can
you point me to how to create the signal handler thread that you
describe? I think that I get it in principle, but am having a hard
time imagining how to actually do it.

Again, many thanks,
Craig
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Passing pointer to member function to different member function that then calls for_each pookiebearbottom@yahoo.com C++ 8 05-24-2005 01:50 PM
write a function such that when ever i call this function in some other function .it should give me tha data type and value of calling function parameter komal C++ 6 01-25-2005 11:13 AM
Passing arrarys from a function to another function. Foxy Kav C++ 1 04-25-2004 02:58 AM
Passing a C++ object's member function to a C function expecing a function pointer! James Vanns C++ 7 01-21-2004 02:39 AM
Passing a pointer to member function as a parameter to another member function Newsgroup - Ann C++ 5 07-30-2003 02:54 AM



Advertisments