2017-11-20 5 views
2

std::bindを使用して、termios.hヘッダーのsigactionへのコールバックとしてメンバー関数を使用しようとしています。私は特別なケアの必要性をメンバーの機能で取ることを理解し、そのような運がない例herehereを読んで従いました。コールバックとしての静的メンバー関数のバインド

Iは、静的関数を通過することができるので、私は、静的関数を残し、それ自体へのポインタ(this)ように、第2の変数を追加した場合、私が良いだろうと思っていないが、そのような運:

// In SerialListener.h 
static void callback(int status, SerialListener *ptr); 

// In the serial listener constructor 

// Set callback 
auto cb = std::bind(&SerialListener::callback, std::placeholders::_1, this); 
sigAct_.sa_handler = cb; 

しかし、エラーが以下の通りである:

// In SerialListener.h 
void callback(int status); 

// In the serial listener constructor 

// Set callback 
auto cb = std::bind(&SerialListener::callback, this, std::placeholders::_1); 
sigAct_.sa_handler = cb; 

error: cannot convert ‘std::_Bind<void (*std::_Placeholder<1>, SerialListener*))(int, SerialListener*)>’ to ‘__sighandler_t {aka void (*)(int)}’ in assignment sigAct_.sa_handler = cb; 

Iはまた、静的実装O/W第二の例の変化を試し...

error: cannot convert ‘std::_Bind<std::_Mem_fn<void (SerialListener::*)(int)>(SerialListener*, std::_Placeholder<1>)>’ to ‘__sighandler_t {aka void (*)(int)}’ in assignment sigAct_.sa_handler = cb; 

エラーはかなり似ています、それは暗黙的にそれが必要ハンドラにバインドを変換することはできませんように見えますが、私は入力タイプとリターンの観点からそれを見たときに生成

それが機能するはずのタイプ。私は何が欠けていますか?

+0

@NageG - クラス/構造体の 'static'メンバーは、通常と同じように機能します:特定のオブジェクトにバインドされておらず、' this'を知らない。 「この」治療は静的ではないメンバーを考慮する。 – max66

+2

Bindは一種のクロージャ*オブジェクト*を返します。関数ポインタには変換できません。 '__sighandler_t'の別のパラメータを呼び出すことはできません。 – StoryTeller

+0

'signal.h'の' sigaction'はありませんか? – VTT

答えて

2

ラムダまたはbindは、シグナルハンドラシグネチャと一致しない関数をシグナルハンドラとして設定するのに役立ちません。シグナルハンドラ関数シグネチャは、不透明ポインタを介してクラスインスタンスを渡す手段を提供しないことに注意してください。あなたができる最善のは、いくつかの静的変数でコンテキストオブジェクトを扱うへのポインタを格納することです:

SerialListener * p_listener; 

void On_Signal(int signal_code) 
{ 
    if(p_listener) 
    { 
     p_listener->DealWith(signal_code); // calling member function 
    } 
} 

p_listener= &my_listener; 

sigAct_.sa_handler = &On_Signal; 

はまた、信号の性質に応じてシグナルハンドラで許可されたアクションの範囲は非常に制限される可能性があることに注意してください。

+0

上記の例で、 'SerialListener'のインスタンスが複数ある場合、' p_listerner'ポイントを関数の引数として渡せない場合、どうすればそれを管理できますか? – DrTarr

+1

@NateGまあ、 'SerialListener'の複数のインスタンスは、同じシグナルを同時に聞くことができません。異なるスレッドから作業することになっている場合は、スレッドのローカル静的変数を使用できます。彼らが異なる信号を扱うことになっている場合は、それぞれが独自の静的変数を使用する 'SerialListener'ごとに別々のハンドラを書く必要があります。 – VTT

+0

わかりました。シリアルポート固有のコードがSerialListenerクラスの外にあったのは難しいですが、このアプローチは私が進めていたものとは逆です。私は、非会員関数へのポインタをSerialListenerクラスに渡しています。そして、そのクラスの内部に、そのシリアルポートとの私の外部コールバックを関連付けることを望みました。私の選択肢は限られているように見え、アーキテクチャを少し修正する必要があります。 – DrTarr

関連する問題