윈도우 C++:fprintf 호출을 위해 stderr를 어떻게 리디렉션할 수 있나요?

StackOverflow https://stackoverflow.com/questions/7664

  •  08-06-2019
  •  | 
  •  

문제

기존 C++ 코드를 다음에서 래핑하고 있습니다. BSD 프로젝트를 자체 사용자 정의 래퍼로 만들고 가능한 한 적은 변경 사항으로 코드에 통합하고 싶습니다.이 코드는 fprintf 인쇄하다 표준 오류 오류를 기록/보고하기 위해.

동일한 프로세스 내의 다른 위치로 이를 리디렉션하고 싶습니다.~에 유닉스 나는 이것을 socketpair 그리고 thread:소켓의 한쪽 끝은 내가 보내는 곳입니다 표준 오류 (전화를 통해 dup2) 다른 쪽 끝은 스레드에서 모니터링되며 여기서 출력을 처리할 수 있습니다.

이 작동하지 않습니다 윈도우 하지만 소켓은 파일 핸들과 동일하지 않기 때문입니다.

웹에서 찾은 모든 문서는 하위 프로세스의 출력을 리디렉션하는 방법을 보여 주지만 이는 내가 원하는 것이 아닙니다.리디렉션하려면 어떻게 해야 하나요? 표준 오류 동일한 프로세스 내에서 출력이 기록될 때 일종의 콜백을 받고 있습니까?(그리고 당신이 그렇게 말하기 전에, 나는 시도해 보았습니다. SetStdHandle 하지만 이 작업을 수행할 방법을 찾을 수 없습니다.)...

도움이 되었습니까?

해결책

Windows에서도 비슷한 기술을 사용할 수 있습니다. 동일한 개념에 대해 다른 단어를 사용하면 됩니다.:) 이 기사는 다음과 같습니다. http://msdn.microsoft.com/en-us/library/ms682499.aspx win32 파이프를 사용하여 다른 프로세스의 I/O를 처리하는 경우 동일한 프로세스 내의 스레드에 대해 동일한 작업을 수행하면 됩니다.물론 귀하의 경우 프로세스의 어느 곳에서나 stderr에 대한 모든 출력이 소비자에게 리디렉션됩니다.

실제로 필요한 다른 퍼즐 조각은 다음과 같습니다. _fdopen 그리고 _open_osfhandle.실제로 다음은 일부 관련 사례입니다. 암호 나는 몇 년 전에 출시했습니다.

DWORD CALLBACK DoDebugThread(void *)
{
    AllocConsole();
    SetConsoleTitle("Copilot Debugger");
    // The following is a really disgusting hack to make stdin and stdout attach
    // to the newly created console using the MSVC++ libraries. I hope other
    // operating systems don't need this kind of kludge.. :)
    stdout->_file = _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT);
    stdin->_file  = _open_osfhandle((long)GetStdHandle(STD_INPUT_HANDLE), _O_TEXT);
    debug();
    stdout->_file = -1;
    stdin->_file  = -1;
    FreeConsole();
    CPU_run();
    return 0;
}   

이 경우 기본 프로세스는 stdio 핸들로 전혀 시작되지 않는 GUI 프로세스였습니다.콘솔을 연 다음 올바른 핸들을 stdout 및 stdin에 밀어 넣어 debug() 함수(stdio 대화형 함수로 설계됨)가 새로 생성된 콘솔과 상호 작용할 수 있도록 합니다.일부 파이프를 열고 stderr를 리디렉션하기 위해 동일한 종류의 작업을 수행할 수 있어야 합니다.

다른 팁

MSVCRT에서 "OS 핸들"이라고 부르는 것은 Win32 핸들이 아니라 혼란을 주기 위해 추가된 또 다른 핸들 레이어라는 점을 기억해야 합니다.MSVCRT는 Unix 핸들 번호를 에뮬레이트하려고 시도합니다. stdin = 0, stdout = 1, stderr = 2 등등.Win32 핸들은 다르게 번호가 매겨져 있으며 해당 값은 항상 4의 배수입니다.파이프를 열고 모든 핸들을 올바르게 구성하려면 손이 지저분해져야 합니다.MSVCRT 소스 코드와 디버거를 사용하는 것이 아마도 요구 사항일 것입니다.

내부 용도로 명명된 파이프를 사용하고 싶지 않다고 언급하셨습니다.아마도 다음에 대한 문서가 있다는 점을 지적할 가치가 있을 것입니다. 파이프 생성() 상태, "익명 파이프는 고유한 이름을 가진 명명된 파이프를 사용하여 구현됩니다.따라서 명명된 파이프에 대한 핸들이 필요한 함수에 익명 파이프에 대한 핸들을 전달할 수 있는 경우가 많습니다." 따라서 비동기 읽기를 위한 올바른 설정으로 유사한 파이프를 생성하는 함수를 작성하는 것이 좋습니다.저는 GUID를 문자열로 사용하는 경향이 있습니다(다음을 사용하여 생성됨). CoCreateGUID() 그리고 StringFromIID()) 고유한 이름을 지정한 다음 중첩된 I/O에 대한 올바른 설정을 사용하여 명명된 파이프의 서버 및 클라이언트 끝을 생성합니다(이에 대한 자세한 내용과 코드는 다음을 참조하세요. http://www.lenholgate.com/blog/2008/02/process-management-using-jobs-on-windows.html).

그런 다음 I/O 완료 포트와 중첩된 I/O를 사용하여 파일을 읽어야 하는 일부 코드를 연결하고 데이터가 도착할 때 비동기 알림을 받습니다...그러나 이 모든 일을 가능하게 하는 꽤 많은 양의 잘 테스트된 라이브러리 코드가 거기에 있습니다.

명명된 파이프를 설정한 다음 이벤트와 중복된 읽기를 수행하는 것이 가능할 수 있습니다. OVERLAPPED 구조를 확인하고 이벤트를 확인하여 데이터가 사용 가능한지 확인하세요.하지만 그렇게 할 수 있는 코드가 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top