2012-05-19 6 views
2

일부 그래픽 엔진을 사용하여 gtk 창 (Opencv/highgui)을 처리하는 C 및 C++ 응용 프로그램을 작성 중입니다. 이 응용 프로그램은 stdout/cout에 약간의 작은 출력을합니다.응용 프로그램에서 콘솔 열기

Windows에서 바탕 화면에서 이러한 유형의 응용 프로그램을 시작하면 자동으로 콘솔이 열리고 사용자에게 표준 출력에 "printf()"또는 "std :: cout"으로 작성된 내용이 표시됩니다.

Linux에서 이전에 열었던 콘솔에서 시작하면 문제가 없습니다. 하지만 바탕 화면 (두 번 클릭)을 통해 시작하면 linux가 관련 콘솔을 열지 않고 stdout/cout에 기록 된 데이터가 손실됩니다. 이것은 Linux (?)에서의 정상적인 동작으로 보입니다.

리눅스 플랫폼에서 컴파일 할 때 내 앱에서 자동으로 콘솔을 열고 싶습니다.

이것은 속량이 this one 인 것처럼 보입니다. 요점은 작동하지 않습니다. 나는 현재 다음과 같은 코드를 가지고 :

#ifndef __WIN32 
    filebuf* console = new filebuf(); 
    console->open("/dev/tty", ios::out); 
    if(!console->is_open()) 
     cerr << "Can't open console" << endl; 
    else 
     cout.ios::rdbuf(console); 
#endif 

내가 점점 계속 "하지 열 수 콘솔"(cerr은 freopen을()를 사용하여 파일에 리디렉션). 콘솔 이름을 바꾸려고 시도했습니다.

console->open("/dev/console", ios::out); 

그러나 변경되지 않았습니다.

나는 올바른 방향으로 가고 있습니까? 다음에 무엇을 시도 할 수 있습니까? 특별히 터미널 애플리케이션 (xterm)을 열어 볼까요? 그렇다면 어떻게하면 내 콘솔과 콘솔을 연결할 수 있을까요?

+1

음 ..특정 데스크탑 환경 (최소한 GNOME)에서는 바탕 화면에 실행 프로그램 ("Windows 바로 가기")을 만들고 해당 응용 프로그램에서 시작된 응용 프로그램을 관련 터미널과 함께 실행하도록 지정할 수 있음을 알고 있습니다. 시도하려는 경우 새 실행 프로그램을 만든 다음 해당 실행 프로그램의 속성을 검사하십시오. 여기서 해당 옵션을 찾을 수 있습니다. 이것이 당신이 원하는 것인지 확실하지 않습니다. – Jonatan

+0

@kebs 그래픽 환경 (예 : gnome 터미널)에서 터미널에서 앱을 실행하면 터미널에 대한 출력과 앱이 열리는 창을 볼 수 있습니다. – ShinTakezou

+0

@fullhack : 예, 알고 있습니다. 그러나이 경우 옵션이 아닙니다. – kebs

답변

5

솔루션 당신이 좋아되지 않을 수도 1

아주 간단한 해결책 : gnome-terminal -x <your_program> <your_args>를 사용하여 터미널에서 응용 프로그램을 실행하는 스크립트가 있습니다. 스크립트를 두 번 클릭하면 터미널이 열립니다.

해결 방법 2

더 복잡 솔루션은 응용 프로그램에 '--noconsole'인수를 추가 비트. 인수가 있으면 응용 프로그램을 실행하십시오. 만약 '--noconsole은'존재하지 않는 :

if(fork() == 0) { 
    execlp("gnome-terminal", "gnome-terminal", "-x", argv[0], "--noconsole", NULL); 
} else { 
    exit(0); 
} 

이 그것이 --noconsole arugment를 사용 gnome-terminal에서 응용 프로그램을 실행하는 자식 프로세스를 생성한다. 말이된다? 약간 해키지만, 헤이, 작동합니다.

해결 방법 3

이 하나가 까다로운 솔루션이지만, 어떤면에서는 더 우아한. 아이디어는 우리의 stdout을 파일로 재지 정하고 tail -f <file_name> --pid=<parent_pid>을 실행하는 터미널을 생성하는 것입니다. 상위 프로세스의 출력을 인쇄하고 상위 프로세스가 종료 될 때 종료합니다.

#include <stdlib.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <string.h> 

// Create terminal and redirect output to it, returns 0 on success, 
// -1 otherwise. 
int make_terminal() { 
    char pidarg[256]; // the '--pid=' argument of tail 
    pid_t child;  // the pid of the child proc 
    pid_t parent;  // the pid of the parent proc 
    FILE* fp;   // file to which output is redirected 
    int fn;   // file no of fp 

    // Open file for redirection 
    fp = fopen("/tmp/asdf.log","w"); 
    fn = fileno(fp); 

    // Get pid of current process and create string with argument for tail 
    parent = getpid(); 
    sprintf(pidarg, "--pid=%d", parent); 

    // Create child process 
    child = fork(); 
    if(child == 0) { 
     // CHILD PROCESS 

     // Replace child process with a gnome-terminal running: 
     //  tail -f /tmp/asdf.log --pid=<parent_pid> 
     // This prints the lines outputed in asdf.log and exits when 
     // the parent process dies. 
     execlp("gnome-terminal", "gnome-terminal", "-x", "tail","-f","/tmp/asdf.log", pidarg, NULL); 

     // if there's an error, print out the message and exit 
     perror("execlp()"); 
     exit(-1); 
    } else { 
     // PARENT PROCESS 
     close(1);  // close stdout 
     int ok = dup2(fn, 1); // replace stdout with the file 

     if(ok != 1) { 
      perror("dup2()"); 
      return -1; 
     } 

     // Make stdout flush on newline, doesn't happen by default 
     // since stdout is actually a file at this point. 
     setvbuf(stdout, NULL, _IONBF, BUFSIZ); 
    } 

    return 0; 
} 

int main(int argc, char *argv[]) { 
    // Attempt to create terminal. 
    if(make_terminal() != 0) { 
     fprintf(stderr, "Could not create terminal!\n"); 
     return -1; 
    } 

    // Stuff is now printed to terminal, let's print a message every 
    // second for 10 seconds. 
    int i = 0; 
    while(i < 10) { 
     printf("iteration %d\n", ++ i); 
     sleep(1); 
    } 

    return 0; 
} 
+0

안녕하세요, 오랜 대답에 감사드립니다. 흥미 롭습니다. – kebs

+0

해결책 1은 @fulhack을 제안한 것과 크게 다르지 않습니다 (다른 데스크탑에서는 gnome 또는 .desktop 단축키를 만듭니다). 모든 플랫폼에서 '그놈 터미널'을 사용할 수 있는지 확신 할 수 없다는 점을 제외하고는 솔루션이 더 이식성이있을 수 있습니다. 솔루션 2는 훌륭합니다. 방금 해봤지만 모든 것이 앱에 포함되어 있지만 다시 '그놈 터미널'이 필요합니다. _all_ linux 플랫폼에서 사용할 수있는 일반 터미널이있을 수 있습니까? 해결책 3은 내일 시도 될 것입니다. – kebs

+0

좋아요, 괜찮 으면 세 번째 해결 방법 이죠, 실제로는 솔과 크게 다르지 않습니다. 2. 나는 후자를 선호하는 경향이 있으며, xterm은 gnome-terminal (예 : KDE 시스템)보다 터미널로 더 일반적이라고 생각합니다. 진짜 완전한 대답을위한 시간을내어 주셔서 감사합니다 ;-) – kebs

3

모든 예제는 콘솔을 "열"는 의미로 파일을 엽니 다. 이것은 GUI에 아무 것도하지 않습니다. 그렇게하기 원한다면, gtk 윈도우를 열고 결과를 출력해야합니다.

+1

좋아요, 제 생각에 말하자면 터미널을 시작하는 것이 좋습니다. 하지만 어떻게이 터미널을 내 앱의 표준 출력에 "연결할"수 있을까요? – kebs

관련 문제