2010-04-14 2 views
5

Я пытался захватить стандартный вывод и STDERR выход из DLL, составленный в MSVC++, что мой Delphi приложение статически ссылки на, но до сих пор не увенчались успехом ,Delphi - Захват стандартный вывод и вывод STDERR из статически связанного MSVC++ компилируется DLL

procedure Test; 
var 
    fs: TFileStream; 

begin 
    fs := TFileStream.Create('C:\temp\output.log', fmCreate or fmShareDenyWrite); 
    SetStdHandle(STD_OUTPUT_HANDLE, fs.Handle); 
    SetStdHandle(STD_ERROR_HANDLE, fs.Handle); 

    dllFunc(0); // Writes to stdout in MSVC++ console app, but not here 
    // fs.Length is always zero 

    fs.Free; 
end; 

Думал, что я был на правильном пути, но он не работает.

  1. Is SetStdHandle() достаточно?
  2. Правильно ли используется TFileStream?
  3. Я правильно использую TFileStream для SetStdHandle()?
  4. Возможно ли, что DLL устанавливает дескрипторы stdout/stderr при загрузке приложения? Если да, то где лучше всего использовать SetStdHandle() или эквивалент?

Любая помощь будет оценена по достоинству.

+1

fmShareDenyWrite не работает с fmCreate - это просто бесполезно. fmCreate или fmShareDenyWrite = fmCreate. – kludg

+0

Интересный Серг, да, я вижу, что fmCreate имеет значение 0xFFFF, которое сделало бы любые флаги режима обмена бесполезными. Странный. – Atorian

ответ

7

Если DLL захватывает стандартный вывод ручки, когда он будет загружен, то вам нужно будет динамически загружать DLL после того как вы изменили стандартный вывод ручки в вашем коде.

+0

Определенно хорошая точка, хотя даже сейчас, когда я динамически загружаю DLL (после вызова SetStdHandle), я все равно не получаю никакого вывода. – Atorian

+0

dthorpe, ваша рекомендация работала (я просто этого не видел). Большое спасибо. – Atorian

0

Если ваше приложение представляет собой консольное приложение, вы можете просто запустить его и перенести все в stdout с перенаправлением. т.е.

C:\MyAppWhichCallsDll.exe > c:\temp\output.log