1

プロジェクトを msvc110 を使用して C++11 標準に移行中ですが、残念ながら、dll で使用されるスレッド変数が、以前のブースト バージョンとは異なる動作をしています。

したがって、もともとこれは msvc90 で機能していました。基本的に、Dll はスレッドが作成された InitDll を呼び出します。スレッドは基本的に、dll のメイン スレッドと共にリスナーとして機能しました。スレッドを作成すると、ハングして何もせず、スレッドの初期化に使用された関数を実行することさえできません。

ブースト バージョンと同じ動作を得るにはどうすればよいか、説明を手伝っていただけませんか?

編集:コード

申し訳ありませんが、コメントのコードに返信できませんでした

アプリケーションは、dll を介してロガーを使用します。非常に単純なコンソール アプリケーションでロガーを使用するには、次のようにします。

#include <Somewhere/Logger.h>

int main()
{
    COOL_LOGGER("Here we go logging on console!");

return 0;
}

コードの記述方法については議論できますが (前述のデモから引用)、dll とスレッドを初期化する方法は次のとおりです。

#include "Logger.h"

#ifdef _WIN32

BOOL APIENTRY DllMain( HMODULE hModule,
                   DWORD  ul_reason_for_call,
                   LPVOID lpReserved
                 )
{
switch (ul_reason_for_call)
{
     case DLL_PROCESS_ATTACH:
    TheLog::InitLog();
            break;
     case DLL_THREAD_ATTACH:
    break;
         case DLL_THREAD_DETACH:
    break;
     case DLL_PROCESS_DETACH:
    break;
}
    return TRUE;
 }

 #endif


 #include <thread>

 void InitLog()
 {
// Do the init taken from library demos
 std::thread m_thread(LogListener);
 }

 void LogListener()
 {
while(!bAppEnd)
{
    std::cin>>str;
    // change log behavior according to the user input
}
 }


 // to stop the thread when shutting down
 void EndLog()
 {
     // retrieve thread thought id or some other way
     thread.join();
 }
4

2 に答える 2

3

問題がDllMain発生すると、実行できることが大幅に制限されます --- 多くの場合、Windows ローダーはアプリを終了するだけで、エラー ハンドラーは呼び出されません。

DllMainハングは、コードが DLL のロードを必要とする何かを実行しているか、別の DLL の初期化を待機していることを示しています。この DLL の呼び出しが完了するまでは、どちらも発生しません。の実装がこれらのいずれかを実行している可能性がありstd::threadます。

編集:問題を回避する1つの方法はstd::call_once、このバックグラウンドスレッドと通信するすべてのエクスポートされた関数で使用して、スレッドが確実に開始されるようにすることです。そうすれば in を使用std::threadDllMainていませんが、「init」関数を公開する必要はありません。

于 2013-02-19T09:47:37.780 に答える
2

InitLog 関数には、その関数にスコープされているように見えるスレッドがあります。関数がすぐに終了すると、スレッドは破棄されます。ただし、結合されていない std::thread (boost::thread ではない) の破棄は、std::terminate を呼び出します。それが起こっていることをテストしたい場合は、終了ハンドラを入れてください。

于 2013-02-19T02:26:56.557 に答える