2011-12-13 104 views
3

我在這裏有點問題。我有一個Python腳本,它調用從C++編譯的二進制文件。 Python腳本有它自己的一組輸出(標準輸出和錯誤),這些輸出很容易禁用。 C++二進制文件具有自己的一組輸出(以標準輸出和錯誤等);源可以改變,但我不是原作者。這是一個問題,因爲我不想在最終的程序中輸出C++,而且我也不希望將來的用戶需要編輯C++源代碼。從Python腳本控制C++輸出

我希望能夠做的是有一些Python方法,它將捕獲發送到標準輸出或錯誤的C++代碼輸出。這可能嗎?如果是這樣,有人能指出我正確的方向嗎?

謝謝!要做到這一點

+0

這取決於您調用二進制文件的方式。例如,如果你使用的是os.system,你可以管輸出,否則可能有一些方法需要研究。在腳本中寫入的調用如何? – bcc32 2011-12-13 21:58:55

+0

對不起,我應該在消息體中發佈它們:它們是通過Python接口導入的,所以Python認爲它調用了其他Python模塊。 – learner 2011-12-13 22:05:33

回答

8

一種方法是:使用os.dupstdoutstderr的文件描述符

  • 重複的蟒蛇。
  • 使用reopen(來自C的stdio)重定向原始文件stdoutstderr以寫入您選擇的文件。

注:reopen是不是從蟒蛇提供直接,但你應該能夠調用它,如下面的例子或者利用現有的任何其他包裝。

此步驟完成後:

  • 每寫coutcerr在C++將寫入到輸出文件。
  • python中的每個print語句都會寫入輸出文件。

但是,由於原來的描述是重複的,你仍然可以(見下例):使用sdout.writestdout.err

  • 使用logging方法配置正確後

    • 打印到原來的stdout/stderrstream參數

    以下代碼使用instant庫測試是使用痛飲這應該是相似的,你有圖書館裹成蟒蛇真正的C++代碼:

    import sys, os 
    import logging 
    from instant import inline 
    
    print 'This is printed from python to stdout' 
    stdout = os.fdopen(os.dup(sys.stdout.fileno()), 'w') 
    stderr = os.fdopen(os.dup(sys.stderr.fileno()), 'w') 
    
    logging.basicConfig(stream=stderr, level=logging.DEBUG) 
    
    redirect = inline("""                              
    void redirect(void) {                              
        freopen("my_stdout.txt", "w", stdout);                        
        freopen("my_stderr.txt", "w", stderr);                        
    }                                   
    """) 
    redirect() 
    
    cout = inline("""                               
    void cout(void) {                               
        std::cout << "This is written from C++ to my_stdout.txt" << std::endl;                
        std::cerr << "This is written from C++ to my_stderr.txt" << std::endl;                
    }                                   
    """) 
    cout() 
    
    print 'This is written from python to my_stdout.txt' 
    
    stdout.write('This is printed from python to stdout\n') 
    stderr.write('This is printed from python to stderr\n') 
    logging.info('This is printed to stderr from python using logging') 
    

    這個例子的輸出是:

    $ python test.py 
    This is printed from python to stdout 
    This is printed from python to stdout 
    This is printed from python to stderr 
    INFO:root:This is printed to stderr from python using logging 
    $ cat my_stdout.txt 
    This is written from C++ to my_stdout.txt 
    This is written from python to my_stdout.txt 
    $ cat my_stderr.txt 
    This is written from C++ to my_stderr.txt 
    

    注:一執行代碼時,可能會得到gcc編譯消息(我已將它們刪除以使示例更清晰)。

  • +0

    如果我明白你已經做了什麼,這會將所有輸出重定向到日誌記錄,包括Python和C++,對吧?如果是這樣的話,那也可以,因爲這個程序的有用輸出實際上是寫入文件的。 – learner 2011-12-13 23:09:47

    0

    您是否在使用subprocess來編譯C++?如果是這樣,您可以設置stderr和stdout的位置:

    nowhere = StringIO() 
    subprocess.call("exit 1", shell=True, stdout=nowhere, stderr=nowhere)