4

C++dll内からpantheiosロギングフレームワークを使用しようとしています。dllのビルドに成功し、テストアプリケーション(C ++ MFCアプリケーション)を介して実行されます。

私は次のインクルードで暗黙のリンクを使用しました:

#include <pantheios/implicit_link/core.h>
#include <pantheios/implicit_link/fe.simple.h>
#include <pantheios/implicit_link/be.console.h>

私のDllMainは、次の呼び出しでpantheiosを初期化します。

extern "C" const char PANTHEIOS_FE_PROCESS_IDENTITY[] = "FinishingLineController";

BOOL APIENTRY DllMain( HMODULE hModule,
                   DWORD  ul_reason_for_call,
                   LPVOID lpReserved)
    {
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
            {
            int panres =  pantheios::pantheios_init(); 

            if(panres < 0)
            {
                fprintf(stderr, "Failed to initialise the Pantheios libraries: %s\n", 
                        pantheios::pantheios_getInitErrorString(panres));

                return FALSE;
            }
            }
            break;
        case DLL_THREAD_ATTACH:
            break;
        case DLL_THREAD_DETACH:
            break;
        case DLL_PROCESS_DETACH:
            pantheios::pantheios_uninit();
            break;
        }
        return TRUE;
    }

次のコードを実行すると、

Microsoft C++ exception: stlsoft::winstl_project::windows_exception at memory location 0x0013da84

pantheios::log_DEBUG("Test logging");

代わりに明示的なリンクを使用しようとしましたが、結果はありませんでした。

4

2 に答える 2

3

AFAICT、あなたのコードは完全で正しいように見えますが、あなたがそれをどのように使用しているか、どこから、そしていつ正確に例外を取得するかを知るのは難しいです。もっと情報を提供すべきだと思います。

私が言いたいのは、 Pantheiosの内部ロギング「ベイルアウト」機能(ログのログ)を使用することをお勧めします。だから、あなたの

fprintf(stderr, "Failed to initialise the Pantheios libraries: %s\n",
    pantheios::pantheios_getInitErrorString(panres));

次のように書く方が良いでしょう

pantheios::util::onBailOut(pantheios::emergency,
    "Failed to initialise the Pantheios libraries",
    PANTHEIOS_FE_PROCESS_IDENTITY,
    pantheios::getInitErrorString(panres));

そうすれば、ログ初期化の失敗自体がログに記録されます。

于 2009-09-23T07:18:53.340 に答える
2

さらにいくつかのテストでは、Windowsアプリケーションではなくコンソールアプリケーションにリンクすると、dllからのログが機能することが示されました。また、バックエンドを「コンソール」ではなく「ファイル」に変更すると、Windowsアプリケーションはファイルに正しくログを記録します。したがって、問題は、Windowsアプリケーションに「コンソール」がないことであるように思われます。

解決策は、標準の出力/入力パイプを新しいコンソールにリダイレクトすることでした。コンソールはデフォルトでは作成されないため、これはwin32アプリケーションに対して実行する必要があります。

void RedirectIOToConsole()
{
    int hConHandle;
    long lStdHandle;
    CONSOLE_SCREEN_BUFFER_INFO coninfo;
    FILE *fp;

    // allocate a console for this app
    AllocConsole();

    // set the screen buffer to be big enough to let us scroll text
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
    coninfo.dwSize.Y = MAX_CONSOLE_LINES;

    SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);

    // redirect unbuffered STDOUT to the console
    lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
    hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
    fp = _fdopen( hConHandle, "w" );
    *stdout = *fp;
    setvbuf( stdout, NULL, _IONBF, 0 );

    // redirect unbuffered STDIN to the console
    lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
    hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
    fp = _fdopen( hConHandle, "r" );
    *stdin = *fp;
    setvbuf( stdin, NULL, _IONBF, 0 );

    // redirect unbuffered STDERR to the console
    lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
    hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
    fp = _fdopen( hConHandle, "w" );
    *stderr = *fp;
    setvbuf( stderr, NULL, _IONBF, 0 );

    // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
    // point to console as well
    std::ios::sync_with_stdio();
}

次に、DllMainからこの関数を呼び出します。

BOOL APIENTRY DllMain( HMODULE hModule,
                   DWORD  ul_reason_for_call,
                   LPVOID lpReserved
                 )
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
    {
        RedirectIOToConsole();

        int panres =  pantheios::pantheios_init();  

        if(panres < 0)
        {
            fprintf(stderr, "Failed to initialise the Pantheios libraries: %s\n", 
                    pantheios::pantheios_getInitErrorString(panres));

            return FALSE;
        }

        // Set the file name for all back-ends.
        //pantheios_be_file_setFilePath("output.log");
    }
    break;
case DLL_THREAD_ATTACH:
    break;
case DLL_THREAD_DETACH:
    break;
case DLL_PROCESS_DETACH:
    pantheios::pantheios_uninit();
    break;
}
return TRUE;
}
于 2009-09-24T06:16:43.427 に答える