2017-12-26 21 views
1

boost :: asio :: steady_timerは、実行可能ファイルで起動されたときに正常に動作しています。 DLLでsteady_timerを開始すると、タイマーはただちに終了します。私のコードで何が間違っていますか? boost :: asioのバグですか?boost :: asio :: steady_timerはboost :: dllで動作しません

api.h:

#include <boost/asio.hpp> 

class my_api { 
public: 
    virtual void startTimer(boost::asio::io_service& ioservice) = 0; 
    virtual ~my_api() {}; 
}; 

Dll.cpp:

#include <iostream> 
#include <boost/dll.hpp> 
#include "api.h" 

class my_plugin : public my_api { 
public: 
    void startTimer(boost::asio::io_service& ioservice) { 
     std::cout << "start timer (15 sec)\n"; 
     boost::asio::steady_timer timer{ ioservice, std::chrono::seconds{ 15 } }; 
     timer.async_wait([](const boost::system::error_code &ec) { std::cout << "15 sec\n"; }); 
    }; 

    ~my_plugin() {}; 
}; 

static boost::shared_ptr<my_api> createPlugin() { 
    return boost::shared_ptr<my_api>(new my_plugin()); 
} 

BOOST_DLL_ALIAS(
    createPlugin, 
    create_plugin 
) 

MAIN.CPP:

#include <boost/dll/import.hpp> 
#include <boost/function.hpp> 
#include <boost/asio.hpp> 
#include <iostream> 
#include "../DLL/api.h" 

int main() { 

    boost::asio::io_service ioservice; 

    /* load dll */ 
    boost::filesystem::path shared_library_path("..\\Debug"); 
    shared_library_path /= "DLL"; 

    boost::function<boost::shared_ptr<my_api>()> creator = boost::dll::import_alias<boost::shared_ptr<my_api>()>(
     shared_library_path, 
     "create_plugin", 
     boost::dll::load_mode::append_decorations 
    ); 
    boost::shared_ptr<my_api> plugin = creator(); 

    /* set timer 10 sec */ 
    std::cout << "start timer (10 sec)\n"; 
    boost::asio::steady_timer timer{ ioservice, std::chrono::seconds{ 10 } }; 
    timer.async_wait([](const boost::system::error_code &ec) { std::cout << "10 sec\n"; }); 

    /* create my_plugin in dll with timer 15 sec */ 
    plugin->startTimer(ioservice); 

    ioservice.run(); 

    return 0; 
} 

出力:

start timer (10 sec) 
start timer (15 sec) 
15 sec 
10 sec 

15秒タイマーは、DLLに呼び出され、すぐに有効期限が切れました。実行可能ファイルで10秒タイマーが呼び出され、うまく動作します。

私はVisual Studio 2017 V15.5.2で作業しています。

+0

'async_wait'の代わりに' wait'を使うだけですか? – sehe

答えて

1

これは何のバグではありません、あなたのstartTimer方法であなたがsteady_timerオブジェクトを作成し、asyncWaitメソッドを呼び出しますが、この方法は、(http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/reference/basic_waitable_timer/async_wait.htmlを参照する参照)、すぐに返すので、(その後、15秒が印刷された)、タイマーオブジェクトが削除されると、ハンドラが呼び出されます。変数ecの値をチェックする必要があります。操作が中止された可能性があります。

主な機能タイマオブジェクトの作品で

、プログラムはこのラインで

ioservice.run(); 

を待っているので、ハンドラは10秒後に呼び出すことができますので。

+0

ありがとうございました。あなたは正しい:dllで開始されたタイマーはキャンセルされた。実行可能なioserviceによってハンドリングされているDLLに、どのようにタイマーを作成できますか? – werner

+0

私はboost dllを使ったことはありませんが、 'async_wait'メソッドを呼びたい場合、' startTimer'メソッドを呼び出した後に 'timer'オブジェクトが存在するはずです。あなたのクラス 'my_plugin'はメンバを格納することができるので、' steady_timer'を 'my_plugin'クラスのメンバとして定義し、' io_service'をパラメータとして持つconstrutorを追加し、 'my_plugin'のコンストラクタで' steady_timer'オブジェクトを 'io_service '。その後、 'startTimer'では、有効期限を設定し、' async_wait'メソッドを実行することができます。 – rafix07

+0

あなたが言ったように、問題は削除されたタイマーでした。今それは正常に動作します。どうもありがとうございました! – werner

関連する問題