从dll使用Pantheios日志框架 IM试图从C++ DLL内部使用PANTIOS日志框架。我已经成功地构建了dll,并通过我的测试应用程序(C++MFC应用程序)执行它

从dll使用Pantheios日志框架 IM试图从C++ DLL内部使用PANTIOS日志框架。我已经成功地构建了dll,并通过我的测试应用程序(C++MFC应用程序)执行它,c++,dll,logging,pantheios,C++,Dll,Logging,Pantheios,我使用了隐式链接,包括: #include <pantheios/implicit_link/core.h> #include <pantheios/implicit_link/fe.simple.h> #include <pantheios/implicit_link/be.console.h> 我尝试使用显式链接,但没有任何结果。AFAICT,您的代码看起来完整正确,但很难知道您是如何使用它的,以及从何处、何时获得异常。我认为你应该提供更多的信息 我想说

我使用了隐式链接,包括:

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

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

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

我想说的一件事是:您可能希望使用的“内部日志”功能—我想是日志的日志。那么,你的

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));

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

一些进一步的测试表明,如果我将dll链接到控制台应用程序而不是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;
}
BOOL-apient-DllMain(HMODULE-HMODULE,
德沃德·乌尔打电话的理由,
LPVOID lpReserved
)
{
开关(ul\u呼叫原因\u)
{
案例DLL\u进程\u附加:
{
重定向iotoconsole();
int panres=pantheios::pantheios_init();
if(panres<0)
{
fprintf(stderr,“未能初始化Pantheios库:%s\n”,
pantheios::pantheios_getInitErrorString(panres));
返回FALSE;
}
//设置所有后端的文件名。
//pantheios_be_文件_setFilePath(“output.log”);
}
打破
案例DLL\u线程\u连接:
打破
案例DLL\u线程\u分离:
打破
案例DLL\u进程\u分离:
pantheios::pantheios_uninit();
打破
}
返回TRUE;
}

Wow!7小时,没有回应。当我面对同样的问题时,我屏住呼吸等待着这个问题的答案。我确实有一个链接,其中提出了一个类似的问题,但还没有尝试看看它是否有效。Joakim,如果链接有帮助,那么告诉我,我会自己找时间试试。我认为你没有提供足够的信息来解释这个问题。您只是在DLL中使用Pantheios,还是从DLL中导出其功能?(顺便说一句,Pantheios团队要求您提供更多关于您报告该问题的项目论坛的信息:)该问题与Pantheios无关。我已经为我找到的解决方案提供了一个我自己的答案。感谢“救助”——功能提示。很高兴知道。这个问题原来与泛神论无关。我已经用我找到的解决方案给出了我自己的答案。一个名叫Timo Geusch的人本周用相同的解决方案解决了pantheios的相同/类似问题,这是巧合吗。有什么建议吗,因为我使用的是MFC DLL,它没有DllMain,但有InitInstance()?同样的程序也适用吗?
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();
}
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;
}