2009-11-09 12 views
9

ile oluşturulan bir konsola Gömülü Python IO'yu yeniden yönlendirme Python IO'yu, Win32 uygulamam için ayrıldığım bir konsola yeniden yönlendirirken sorun yaşıyorum. Yönlendirmem gereken bir Python özel akışı var mı?AllocConsole

İşte daha çok ya da daha az ne (hata kaldırıldı Kontrolden vs.) şimdi yapıyorum:

int __stdcall WinMain(/*Usual stuff here*/) { 
    // Create the console 
    AllocConsole(); 
    SetConsoleTitle(L"My Console"); 

    // Redirect Standard IO Streams to the new console 
    freopen("CONOUT$","w",stdout); 
    freopen("CONOUT$","w",stderr); 
    freopen("CONIN$","r",stdin); 

    // Test the console: 
    printf("This Works.\r\n"); 
    cout << "So Does this" << endl; 

    // Python Stuff (This is where it fails) 
    Py_Initialize(); 
    PyRun_SimpleString("print('I don't work.')\n"); 
    Py_Finalize(); 
} 

aynı şeyi çalıştırmak ama olursa (BTW Visual Studio 05,) bir konsol uygulaması olarak AllocConsole çağrısını kaldır ve her şey çalışır. Ne eksik olduğumu bilen var mı?

DÜZENLEME: Sadece açıklama için, C API'sinden bunu yapmanın bir yolunu arıyorum.

BAŞKA BİR DÜZENLEME: Alex'in çözümü doğru, ancak Python 3.x kullanan herhangi biri için muhtemelen yeni API'da PyFile_FromString işlevinin eksik olduğunu göreceksiniz. sys.stderr için benzer Python'un print çalışması için (muhtemelen bir open('CONOUT$', 'wt') kadar) Python tarafında

PyObject* sys = PyImport_ImportModule("sys"); 
PyObject* io = PyImport_ImportModule("io"); 
PyObject* pystdout = PyObject_CallMethod(io, "open", "ss", "CONOUT$", "wt"); 
if (-1 == PyObject_SetAttrString(sys, "stdout", pystdout)) { 
    /* Announce your error to the world */ 
} 
Py_DECREF(sys); 
Py_DECREF(io); 
Py_DECREF(pystdout); 

cevap

9

Set sys.stdout ve: en iyi alternatif olmayabilir, ben bu Python 3.x çalışıyor bulundu ve sys.stdin. (Bunun bir C uzantısından yapılabilmesi için daha hızlı yollar vardır, ancak en basit yol, Python ifadelerini yalnızca import sys önde ;-) ile yürütmektir.

Nedeni: Python'un çalışma zamanı, başlangıçta, standart FD'lerin kapalı olduğunu, sys.stdout ve arkadaşlarının buna uygun olarak ayarlandığını ve tekrar kontrol edip farklı bir şekilde ayarlamayacağını çünkü bu nedenle bunları yalnızca kendiniz ayarlamanıza, açıkça ve iyi ol. Bunun tam karşılığı olan

PyObject* sys = PyImport_ImportModule("sys"); 
PyObject* pystdout = PyFile_FromString("CONOUT$", "wt"); 
if (-1 == PyObject_SetAttrString(sys, "stdout", pystdout)) { 
    /* raise errors and wail very loud */ 
} 
Py_DECREF(sys); 
Py_DECREF(pystdout); 

C-API düzeyinde her şeyi istekli iseniz, bu birkaç satır alacak, ama tabii ki yapılabilir ... Tek Python satırı:

sys.stdout = open('CONOUT$', 'wt') 
+0

sayesinde ben ipucu takdir ediyorum ama ben daha açık olmalıydı sanırım: C API ile bunu yapma bir yol arıyorum. Dosya/sys API'sinin dokümantasyonu, en iyi ihtimalle sivridir. Bu yüzden kendi başıma bulmam için çok şansım olmadı. – Toji

+0

Tamam, cevabı düzenlememe izin ver. –

+0

Burada, bir Python hattının C API ile 7+ satırına nasıl dönüştürüleceği gösterildi (hata tanılama gereksinimlerine bağlı olarak daha fazla olabilir). (Python ve C-API kodlayıcılarının neden deneyimlendiğine bakın, bunun yerine sadece Python kod dizesini C yerine çalıştırmayı önerir? -). –

1

Sadece gömülü python'u çıktılarını bir dosyaya yönlendirmesi çok daha kolaydır.

bu kodu deneyin:

PyRun_SimpleString("import sys\n"); 
PyRun_SimpleString("sys.stdout = sys.stderr = open(\"C:\\embedded_log_file.txt\", \"w\")\n");