2010-04-14 8 views
5

Tôi đã cố gắng để nắm bắt stdoutstderr đầu ra từ một DLL được biên soạn trong MSVC++ rằng ứng dụng Delphi tôi tĩnh liên kết đến, nhưng cho đến nay đã không thành công .Delphi - Capture stdout và đầu ra stderr từ liên kết tĩnh MSVC++ biên soạn 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; 

Tôi đã đi đúng hướng nhưng không hoạt động.

  1. Có phải SetStdHandle() đủ không?
  2. TFileStream có phù hợp để sử dụng ở đây không?
  3. Tôi có sử dụng TFileStream đúng cho SetStdHandle() không?
  4. Có thể DLL đặt bộ xử lý stdout/stderr của nó khi ứng dụng tải không? Nếu vậy, đâu là nơi tốt nhất để sử dụng SetStdHandle() hoặc tương đương?

Mọi trợ giúp sẽ được đánh giá cao.

+1

fmShareDenyWrite không hoạt động với fmCreate - nó chỉ đơn giản là vô dụng. fmTạo hoặc fmShareDenyWrite = fmTạo. – kludg

+0

Thú vị Serg, vâng tôi thấy rằng fmCreate có giá trị 0xFFFF mà sẽ làm cho bất kỳ chế độ chia sẻ cờ vô ích. Odd. – Atorian

Trả lời

7

Nếu DLL lấy stdout xử lý khi được tải, thì bạn sẽ cần tải động DLL sau khi bạn đã thay đổi xử lý stdout trong mã của mình.

+0

Chắc chắn là một điểm tốt, mặc dù ngay cả bây giờ mà tôi tải DLL động (sau khi gọi SetStdHandle), tôi vẫn nhận được không có đầu ra. – Atorian

+0

dthorpe, đề xuất của bạn đã hoạt động (tôi không thấy nó). Cảm ơn nhiều. – Atorian

0

Nếu ứng dụng của bạn là một ứng dụng bảng điều khiển, bạn chỉ có thể chạy điều và chụp mọi thứ để stdout với chuyển hướng. tức là

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