首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从dll使用Pantheios日志记录框架

从dll使用Pantheios日志记录框架
EN

Stack Overflow用户
提问于 2009-09-22 13:42:23
回答 2查看 1.8K关注 0票数 4

我正在尝试从c++动态链接库内部使用pantheios日志记录框架。我已经成功地构建了动态链接库,并且它通过我的测试应用程序(C++ MFC应用程序)执行。

我使用了隐式链接,如下所示:

代码语言:javascript
复制
#include <pantheios/implicit_link/core.h>
#include <pantheios/implicit_link/fe.simple.h>
#include <pantheios/implicit_link/be.console.h>

我的DllMain使用以下调用初始化pantheios:

代码语言:javascript
复制
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

代码语言:javascript
复制
pantheios::log_DEBUG("Test logging");

我尝试使用显式链接,但没有任何结果。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-09-24 06:16:43

一些进一步的测试表明,如果我将dll链接到控制台应用程序而不是windows应用程序,则来自dll的日志记录可以正常工作。如果我将后端改为" file“而不是"console”,windows应用程序会正确地记录到该文件中。所以问题似乎是windows应用程序没有“控制台”。

解决方案是将标准输出/输入管道重定向到新的控制台。必须为win32应用程序执行此操作,因为默认情况下不会创建控制台。

代码语言:javascript
复制
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调用此函数。

代码语言:javascript
复制
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;
}
票数 2
EN

Stack Overflow用户

发布于 2009-09-23 07:18:53

AFAICT,你的代码看起来是完整和正确的,但很难知道你是如何使用它的,从哪里,以及何时你得到了异常。我认为你应该提供更多的信息。

我要说的一件事是:您可能想要使用Pantheios的内部日志"bailout“功能--我想是日志。

代码语言:javascript
复制
fprintf(stderr, "Failed to initialise the Pantheios libraries: %s\n",
    pantheios::pantheios_getInitErrorString(panres));

会更好地写成

代码语言:javascript
复制
pantheios::util::onBailOut(pantheios::emergency,
    "Failed to initialise the Pantheios libraries",
    PANTHEIOS_FE_PROCESS_IDENTITY,
    pantheios::getInitErrorString(panres));

这样,日志初始化失败本身就会被记录下来。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1460185

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档