2016-10-25 20 views
0

私は、コマンドラインアプリケーション用に次のコード(サンプル)を用意しています。 Disconnectが呼び出されたことを確認したいと思います。ctrl + cイベントです。 そのため、ハンドラを追加しました。 CTRL +Cが押されたときに、ハンドラが上Disconnect()を呼び出すための有効なFooを目的としているように、 私は、CtrlHandlerにメンバ関数を作るだろうか?メンバ関数をSetConsoleCtrlHandler()に渡す方法は?

#include <windows.h> 

class Foo 
{ 

public : 
    Foo() 
    { 
     Connect(); 
    } 
    virtual ~Foo() 
    { 
     Disconnect(); 
    } 

    protected: 
    Run(); 
    Connect(); 
    Disconnect(); 
}; 

BOOL CtrlHandler(DWORD fdwCtrlType) 
{ 
    switch (fdwCtrlType) 
    { 
     // Handle the CTRL-C signal. 
    case CTRL_C_EVENT: 
     //Disconnect somehow 
     return(TRUE); 
    default: 
     return FALSE; 
    } 
} 




int main(int argc, char* argv[]) 
{ 
    SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE); 
    Foo myFoo; 
    myFoo.Run();   
} 
+1

いいえ「CtrlHandler」をメンバー関数にすることはできません。メンバ関数は非メンバ関数と同じではなく、メンバ関数は呼び出すクラスの*インスタンス*を必要とします。 ['SetConsoleCtrlHandler'](https://msdn.microsoft.com/en-us/library/windows/desktop/ms686016(v = vs.85).aspx)関数は単にインスタンスまたは他のユーザーを提供する方法がありません-データ。 SetConsoleCtrlHandler'に 'static'メンバ関数またはキャプチャレスラムダを渡すことができますが、それはあなたがしたいことを本当に助けません。 –

答えて

1

唯一のオプションは、コールバックのコンテキストを自分で管理することです。 Runを再入力できないシングルスレッドアプリケーションでは、非常に簡単な方法です。

#include <windows.h> 

class Foo 
{ 

public : 
    Foo() 
    { 
     Connect(); 
    } 
    virtual ~Foo() 
    { 
     Disconnect(); 
    } 

    protected: 
    static Foo* current_foo; 
    static BOOL CtrlHandler(DWORD fdwCtrlType) 
    { 
    switch (fdwCtrlType) 
    { 
     // Handle the CTRL-C signal. 
    case CTRL_C_EVENT: 
     current_foo->Disconnect(); 
     return(TRUE); 
    default: 
     return FALSE; 
    } 
    } 

    Run() { 
     Foo::current_foo = this; 
     SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE); 
     // Other things 
    } 
    Connect(); 
    Disconnect(); 
}; 

Foo* Foo::current_foo = nullptr;  

int main(int argc, char* argv[]) 
{ 
    Foo myFoo; 
    myFoo.Run();   
} 

私は繰り返し言いますが、簡単なアプリケーションでは、より堅牢なものが必要です。

+0

しかし、あなたのコードでは、誤っていないと 'CtrlHandler'は' Foo'のメンバーです。だから私は\t 'SetConsoleCtrlHandler'をメンバ関数へのポインタで呼び出すことはできませんか? – biolightning

+0

@biolightning ** static **メンバー関数です。インスタンスを呼び出す必要はありません。また、c APIのコールバックとして使用できます。 – StoryTeller

+0

オハイオ州、大丈夫です。しかし、 'SetHolder'を' SetConsoleCtrlHandler'に渡すにはどうしたらいいですか?私は 'C2065 'のCtrlHandler'宣言されていない識別子'コンパイルエラーを取得します。クラスのスコープを追加すると、 'クラス 'Foo'' – biolightning

関連する問題