2017-03-29 16 views
1

関数としてmy_handlerを使用すると、エラーはありませんが、別のメソッドを使用する必要があるため、できません。シグナル処理エラー

私は以下のコードビルドする場合: エラー:(?あなたは忘れた 'を()')のメンバーfuncti の不正な使用を

これはC++

void Client::my_handler(int s){ 
    if (s == SIGINT){ 
     printf("SIGINT\n"); 
    // here I have to use stop_thread method 
    } 
} 


int main (int argc, const char **argv) { 
    Client client(argc, argv); 
    client.before_start(); 

    struct sigaction sigIntHandler; 

    sigIntHandler.sa_handler = (__sighandler_t) client.my_handler; //error here 
    sigemptyset(&sigIntHandler.sa_mask); 
    sigIntHandler.sa_flags = 0; 
    sigaction(SIGINT, &sigIntHandler, NULL); 

    client.run(); 

    return 0; 
} 
+0

また、信号ハンドラで何をしようとしているかに注意してください。オプションは非常に限られています。私はあなたが安全に使うことができるものを手にしているのではないかと心配しています。 – user4581301

答えて

4
の私の最初のプログラムです。

C++では、メンバ関数(ここではclient.my_handlerなどのクラスインスタンスに関連付けられた関数)は、通常の関数(ここではint main(int arg, const char** argv)など)と同じではありません。そのため、client.my_handler__sighandler_tにキャストできません。

Client::my_handlerには、Client*という非表示のパラメータがあります。だから、実際には、それは(特定の視点からの)署名はvoid my_handler(Client* this, int s)のように見えます。 C++は、thisの変数をthis->(ほとんどの場合)を行うことなく参照できるように、バックグラウンドで何かをしています。 __sighandler_tは、関数ポインタのエイリアスですが、client.my_handlerは実際には2つの次のとおりです。そして、あなたは、コール

client.my_handler(SIGINT) 
C++は

my_handler(&client, SIGINT) 

にたぶん今、あなたが問題を見ることができる翻訳され

ような何かを行うときポインタ:my_handlerの関数ポインタとclientのポインタ。

シグナルハンドラは、より一般的な関数オブジェクト(関数ポインタといくつかの他のデータ)ではなく、関数ポインタのみを受け入れます。シグナル処理はCのものですが、関数オブジェクトはC++のものです。

シグナルハンドラの唯一の解決策は、ある種のグローバル変数です。

0

@SJLは、なぜこれが機能しないのかを説明し、Cスタイルの回避策を提供しています。

ブーストを使用できる場合は、より多くのC++スタイルの信号を処理するためにboost::asio::signal_setを使用できます。 async_wait functionは、ラムダ、バウンドメンバ関数ポインタ、または適切なシグネチャを持つ他の呼び出し可能な型を受け取ることができます。

+0

タイプありがとうございますが使用できません – Bando