从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;
}