WinAPI-프로그램의 모든 stdout과 외부 DLL을 Win32 표준 출력 핸들로 리디렉션하는 방법은 무엇입니까?

nonbirithm

콘솔 핸들을 사용하는 대신 Windows 응용 프로그램의 모든 표준 출력을 Win32 표준 출력 핸들로 리디렉션 할 수 있기를 원합니다.

컨텍스트를 위해 Emacs Win32 FAQ는 다음과 같이 말합니다.

stdin 및 stdout 대신 콘솔에 대한 핸들 (CON 또는 CON :)을 명시 적으로 사용하는 프로그램은 Emacs의 하위 프로세스로 사용할 수 없으며 쉘 모드에서도 작동하지 않습니다. [...] 둘 중 하나를위한 편리한 방법은 없습니다. Emacs 또는 쉘 모드에서 사용되는 쉘은 이러한 프로세스의 입력 및 출력을 콘솔에서 입력 및 출력 파이프로 리디렉션합니다. 유일한 해결 방법은 콘솔을 직접 사용하지 않는 프로그램의 다른 구현을 사용하는 것입니다. ( https://www.gnu.org/software/emacs/manual/html_node/efaq-w32/Subprocess-hang.html )

FAQ에 설명 된 문제가 있습니다. Emacs에서 시작하면 프로그램이 실행되지만 shell프로그램이 종료 될 때까지 출력이 Emacs 창에 표시 되지 않습니다. 마치 stdout이 버퍼링되고 실행 중일 때 플러시하지 않은 것처럼 말입니다. 동일한 프로그램은 cmd.exe또는 ConEmu 에서 실행되는 경우 예상대로 실시간으로 stdout을 출력 합니다.

내가 달성하고 싶은 것은 프로그램의 모든 출력이 Emacs 쉘에 나타나도록 만드는 것입니다. 그래서 그것이 인쇄되는 즉시 컴파일러 오류 위치로 이동할 수 있습니다. 이 작업을 수행하기 위해 프로그램 소스를 다시 작성할 의향이 있습니다. "콘솔 핸들"대신 "stdin 및 stdout"을 사용하여 "다른 구현"세부 사항이 필요한지 알고 싶습니다.

내가 이해하는 바에서 :

  1. Windows에는 C 런타임 ( printf등) 및 Win32 계층 (등)을 포함하여 여러 종류의 I / O가 ReadFile있습니다.
  2. 나는 "표준 입력과 표준 출력이"을 참조 겠지 STD_INPUT_HANDLE하고 STD_OUTPUT_HANDLE있는 수정할 수 있습니다 SetStdHandle().
  3. 프로그램에 의해로드 된 외부 DLL은 C 런타임 stdinstdout파이프를 상속 하지만 이는 호출이 호출되기 전에 프로그램 초기화시 발생 SetStdHandle()하므로 출력을 리디렉션하려면 다른 작업을 수행해야합니다.

이 코드를 사용해 보았습니다.

#include <windows.h>
#include <cstdlib>

int main()
{
    HANDLE hStdout = CreateFile(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    HANDLE hStdin = CreateFile(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    SetStdHandle(STD_OUTPUT_HANDLE, hStdout);
    SetStdHandle(STD_ERROR_HANDLE, hStdout);
    SetStdHandle(STD_INPUT_HANDLE, hStdin);

    std::cout << "Hello, world." << std::endl;
    printf("Hello, world.\n");
    std::cin.get();

    return 0;
}

이것 만의 용도에 대한 원하는 효과를 갖는다 printfstd::cout리디렉션 코드와 같은 이진 이내. 내 프로그램은 사용하는 외부 DLL을로드 printf하고 출력은 리디렉션되지 않습니다.

또한 AllocConsole()부모 프로세스 (Emacs)와 통합되지 않는 별도의 창이 열리므로 사용하고 싶지 않습니다. 내가 원하는 것은 모든 stdout을 리디렉션하여 다른 창 대신 프로그램을 실행하는 동일한 터미널 / 콘솔 내에 표시되도록하는 것입니다 (해당되는 경우). 나는 사용하지 않기 때문에 어떤 이유로 든 항상 AllocConsole()같은 코드가 _open_osfhandle((long)hStdout, O_WRONLY|O_TEXT)반환 -1되므로 여기에dup2() 설명 된대로 사용할 수없는 것 같습니다 .

또한보십시오:

nonbirithm

위에서 제공 한 코드 예제를 사용한 다음 setvbuf(stdout, NULL, _IONBF, 4096)버퍼링되지 않은 출력을 설정하기 위해 호출 하여 원하는 결과를 얻었습니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관