#c #signals
#c #сигналы
Вопрос:
У меня такая проблема с signal()
:
Этот код компилируется нормально:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void terminate( int param )
{
printf ( "Terminating program...n" );
exit( 1 );
}
int main()
{
signal( SIGTERM, terminate );
return 0;
}
Однако следующий код выдает эту ошибку:
g -Wall -c -g goober.cpp
goober.cpp: In member function `void GOOBER::yarrgh()':
goober.cpp:5: error: argument of type `void (GOOBER::)(int)' does not match `
void (*)(int)'
make: *** [goober.o] Error 1
goober.h:
#ifndef GOOBER_H
#define GOOBER_H
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
using namespace std;
class GOOBER {
public:
GOOBER(){}
~GOOBER(){}
void yarrgh();
void terminate( int param );
};
#endif
goober.cpp:
#include "goober.h"
void GOOBER::yarrgh()
{
signal( SIGTERM, terminate );
}
void GOOBER::terminate( int param )
{
printf( "Terminating program...n" );
exit( 1 );
}
driver.cpp:
#include "goober.h"
using namespace std;
int main()
{
GOOBER G;
G.yarrgh();
return 0;
}
Я не вижу никакой разницы в коде, кроме того, что я вызываю signal()
в члене. Есть идеи, что не так и как это исправить?
Ответ №1:
Вам нужно объявить свою terminate()
функцию как static
:
class GOOBER {
// ...
static void terminate(int param);
};
Это связано с тем, что, будучи нестатической функцией-членом, terminate()
функция ожидает, что ей будет передан (скрытый) this
параметр, указывающий на некоторый экземпляр объекта. Поскольку механизм сигналов не знает об этом (или о чем-либо еще в C ), вам нужно использовать static
функцию, чтобы не было скрытого this
параметра.
Комментарии:
1. Я бы не доверял статическому члену иметь правильные требования к связыванию для функции C.
Ответ №2:
Я могу сказать вам, что не так:
Вы не можете использовать нестатическую функцию-член как обычный указатель на функцию. Функции-члены всегда имеют неявный this
аргумент, который предоставляется (неявно) вызывающей стороной. C API не может этого сделать.
Ответ №3:
Terminate должна быть статической функцией в классе.
Ответ №4:
Сигнатура функции-члена отличается от обычной функции, которая не принадлежит ни одному классу. Однако статическая функция-член имеет ту же сигнатуру, что и обычная функция. Итак, вы могли бы объявить свою функцию-член terminate в классе GOOBER как статическую.