2009-09-22 19 views
4

我試圖從C++ dll中使用pantheios日誌框架。我已經成功構建了dll,並通過我的測試應用程序(C++ MFC應用程序)執行。從一個dll使用Pantheios日誌框架

我已經使用隱式鏈接與以下包括:

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

我試圖使用顯式鏈接,而沒有任何結果。

+0

哇! 7小時,沒有迴應。當我面對同樣的問題時,我正在等待這個問題的答案。我有一個鏈接http://sourceforge.net/projects/pantheios/forums/forum/647484/topic/1639420,提出了類似的問題,但沒有嘗試過,看它是否會工作。 Joakim,如果鏈接有幫助,那麼告訴我,我會抽出時間親自嘗試。 – ossandcad 2009-09-22 21:14:20

+1

我認爲你沒有提供足夠的信息來解釋這個問題。你只是在DLL中使用Pantheios,還是從DLL中導出其功能? (順便說一下,Pantheios團隊已經要求您提供關於您報告該問題的項目論壇的更多信息:http://sourceforge.net/projects/pantheios/forums/forum/475314/topic/3407328?message=7642468) – JamieH 2009-09-23 06:57:10

+1

問題原來是與非pantheios有關。我用我找到的解決方案提供了我自己的答案。 – 2009-09-24 06:19:23

回答

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; 
} 
+0

有人說Timo Geusch本週使用相同的解決方案解決了與pantheios相同/相似的問題是否是巧合? http://codeblog.bsdninjas.co.uk/index.php?/archives/134-Using-pantheios-to-log-inside-a-C++-JNI-DLL.html。任何建議,因爲我使用的MFC DLL,它沒有一個DllMain,但有一個InitInstance()?同樣的程序是否適用? – ossandcad 2009-09-25 21:43:49

3

AFAICT,你的代碼看起來是完整和正確的,但很難知道你是如何使用它,以及從哪裏,以及在何時發生異常。我想你應該提供更多信息。

我想說的一件事是:你可能想要使用Pantheios的內部日誌記錄「bailout」功能 - 日誌記錄,我想。所以,你的

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

這樣,你的日誌初始化失敗本身將被記錄。

+1

感謝您的「救助」功能提示。很高興知道。 問題原來是與非pantheios有關。我用我找到的解決方案提供了我自己的答案。 – 2009-09-24 06:18:14