2017-09-21 11 views
0

CodeBlocks/MinGW C++ 컴파일러에서 "_popen()"을 사용하여 함수를 컴파일하려고합니다. 그러나 컴파일러는 함수를 찾을 수 없습니다. stdio.h 헤더 파일을 grep하고 "_popen"이 정의되어 있지만 ifdef 때문에 선택되지 않았 음을 확인합니다. CodeBlocks 컴파일러를 사용하여 _popen, _wpopen, popen 또는 wpopen 또는 이와 유사한 것을 컴파일 할 수 있도록 컴파일을 설정하는 방법은 무엇입니까?Windows CodeBlocks/MinGW에서 _popen() 및 _pclose()를 찾을 수 없습니다. 16.01

여기 CodeBlocks에서 컴파일되지 않습니다 코드의 예 :

#include <cstdio> 
#include <cstdlib> 
#include <deque> 

using namespace std; 

// System(cmd) and capture output of command 
int SystemCapture(string cmd, deque<string>& cmdout, int& RetCode) 
{ 
    RetCode = 0; 
    FILE* Pipe = _popen(cmd.c_str(), "rt"); 
    if(!Pipe) 
     return -1; 

    char Buffer[128]; 

    while(fgets(Buffer, 128, Pipe)) { 
     cmdout.push_back(Buffer); 
    } 

    if (feof(Pipe)) { 
    RetCode =_pclose(Pipe); 
    return 0; 
    } 
    return -2; 
} 

는 어떤 차이가 있는지 모르겠어요,하지만 내 컴파일러 플래그 ++ (11)가 활성화 c를 가지고있다.

오류 메시지 _popen의 프로토 타입이 헤더 파일 "stdio.h"에 정의되어 있지 않은 것처럼 보입니다. 그러나 Microsoft 설명서에 이것이 _popen()이있는 곳이라고 나와 있습니다.

오류 메시지 BUILD.LOG 탭에서 : 나는 사용법 #include 아래 내 자신의 프로토 타입을 추가하는 시도

mingw32-g++.exe -Wall -fexceptions -g -std=c++11 -g 
    -c MyCode.cpp -o obj\Debug\MyCode.o 

MyCode.cpp:270:42: error: '_popen' was not declared in this scope 
    FILE* Pipe = _popen(cmd.c_str(), "rt"); 
            ^
MyCode.cpp:281:27: error: '_pclose' was not declared in this scope 
    RetCode =_pclose(Pipe); 
        ^
Process terminated with status 1 (0 minute(s), 1 second(s)) 
2 error(s), 0 warning(s) (0 minute(s), 1 second(s)) 

: 여기 Codeblocks에서 오류 메시지의

FILE* _popen (const char*, const char*); 
int _pclose (FILE*); 

는 그런 컴파일러의 링크 단계가 실패 다음을 입력하십시오 :

undefined reference to _popen(char const*, char const*) 
undefined reference to _pclose(_iobuf*) 

다음과 같은 변형으로 popen의 이름을 변경했습니다. popen, _popen, _wpopen, wpopen

아무 래도 그 행운이 없습니다. 내가 STDIO.H을 grep을 경우

그러나, 나는

+0

당신은'using namespace std; '를 사용하지 않고 코드를 컴파일하지 않습니다. – kiwixz

+1

컴파일 또는 링커 오류를 게시하여 컴파일 또는 링크 문제인지 확인할 수 있습니다. –

+0

ifdef가 당신을 괴롭 히고 있습니까? ** _ UNICODE **로 프로그램을 컴파일한다면 대신에'_wpopen'을 사용해야합니다. – kiwixz

답변

0

내가 Codeblocks /는 MinGW와는 popen/만일 pclose 문제를 알아낼 수 ...는 popen 프로토 타입 주위 IFDEF의의를 참조하십시오. 그래서 대신 CreateProcess() 및 CreatePipe()를 사용하여 문제를 해결했습니다. 내가 Codeblocks 작동하지는 popen에 대해 초조해 이유

//C++11 
#include <cstdio> 
#include <iostream> 
#include <windows.h> 
#include <cstdint> 
#include <deque> 
#include <string> 
#include <thread> 

using namespace std; 

int SystemCapture(
    string   CmdLine, //Command Line 
    string   CmdRunDir, //set to '.' for current directory 
    string&  ListStdOut, //Return List of StdOut 
    string&  ListStdErr, //Return List of StdErr 
    uint32_t&  RetCode) //Return Exit Code 
{ 
    int     Success; 
    SECURITY_ATTRIBUTES security_attributes; 
    HANDLE    stdout_rd = INVALID_HANDLE_VALUE; 
    HANDLE    stdout_wr = INVALID_HANDLE_VALUE; 
    HANDLE    stderr_rd = INVALID_HANDLE_VALUE; 
    HANDLE    stderr_wr = INVALID_HANDLE_VALUE; 
    PROCESS_INFORMATION process_info; 
    STARTUPINFO   startup_info; 
    thread    stdout_thread; 
    thread    stderr_thread; 

    security_attributes.nLength    = sizeof(SECURITY_ATTRIBUTES); 
    security_attributes.bInheritHandle  = TRUE; 
    security_attributes.lpSecurityDescriptor = nullptr; 

    if (!CreatePipe(&stdout_rd, &stdout_wr, &security_attributes, 0) || 
      !SetHandleInformation(stdout_rd, HANDLE_FLAG_INHERIT, 0)) { 
     return -1; 
    } 

    if (!CreatePipe(&stderr_rd, &stderr_wr, &security_attributes, 0) || 
      !SetHandleInformation(stderr_rd, HANDLE_FLAG_INHERIT, 0)) { 
     if (stdout_rd != INVALID_HANDLE_VALUE) CloseHandle(stdout_rd); 
     if (stdout_wr != INVALID_HANDLE_VALUE) CloseHandle(stdout_wr); 
     return -2; 
    } 

    ZeroMemory(&process_info, sizeof(PROCESS_INFORMATION)); 
    ZeroMemory(&startup_info, sizeof(STARTUPINFO)); 

    startup_info.cb   = sizeof(STARTUPINFO); 
    startup_info.hStdInput = 0; 
    startup_info.hStdOutput = stdout_wr; 
    startup_info.hStdError = stderr_wr; 

    if(stdout_rd || stderr_rd) 
     startup_info.dwFlags |= STARTF_USESTDHANDLES; 

    // Make a copy because CreateProcess needs to modify string buffer 
    char  CmdLineStr[MAX_PATH]; 
    strncpy(CmdLineStr, CmdLine.c_str(), MAX_PATH); 
    CmdLineStr[MAX_PATH-1] = 0; 

    Success = CreateProcess(
     nullptr, 
     CmdLineStr, 
     nullptr, 
     nullptr, 
     TRUE, 
     0, 
     nullptr, 
     CmdRunDir.c_str(), 
     &startup_info, 
     &process_info 
    ); 
    CloseHandle(stdout_wr); 
    CloseHandle(stderr_wr); 

    if(!Success) { 
     CloseHandle(process_info.hProcess); 
     CloseHandle(process_info.hThread); 
     CloseHandle(stdout_rd); 
     CloseHandle(stderr_rd); 
     return -4; 
    } 
    else { 
     CloseHandle(process_info.hThread); 
    } 

    if(stdout_rd) { 
     stdout_thread=thread([&]() { 
      DWORD n; 
      const size_t bufsize = 1000; 
      char   buffer [bufsize]; 
      for(;;) { 
       n = 0; 
       int Success = ReadFile(
        stdout_rd, 
        buffer, 
        (DWORD)bufsize, 
        &n, 
        nullptr 
       ); 
       printf("STDERR: Success:%d n:%d\n", Success, (int)n); 
       if(!Success || n == 0) 
        break; 
       string s(buffer, n); 
       printf("STDOUT:(%s)\n", s.c_str()); 
       ListStdOut += s; 
      } 
      printf("STDOUT:BREAK!\n"); 
     }); 
    } 

    if(stderr_rd) { 
     stderr_thread=thread([&]() { 
      DWORD  n; 
      const size_t bufsize = 1000; 
      char   buffer [bufsize]; 
      for(;;) { 
       n = 0; 
       int Success = ReadFile(
        stderr_rd, 
        buffer, 
        (DWORD)bufsize, 
        &n, 
        nullptr 
       ); 
       printf("STDERR: Success:%d n:%d\n", Success, (int)n); 
       if(!Success || n == 0) 
        break; 
       string s(buffer, n); 
       printf("STDERR:(%s)\n", s.c_str()); 
       ListStdOut += s; 
      } 
      printf("STDERR:BREAK!\n"); 
     }); 
    } 

    WaitForSingleObject(process_info.hProcess, INFINITE); 
    if(!GetExitCodeProcess(process_info.hProcess, (DWORD*) &RetCode)) 
     RetCode = -1; 

    CloseHandle(process_info.hProcess); 

    if(stdout_thread.joinable()) 
     stdout_thread.join(); 

    if(stderr_thread.joinable()) 
     stderr_thread.join(); 

    CloseHandle(stdout_rd); 
    CloseHandle(stderr_rd); 

    return 0; 
} 

int main() 
{ 
    int   rc; 
    uint32_t  RetCode; 
    string   ListStdOut; 
    string   ListStdErr; 

    cout << "STARTING.\n"; 

    rc = SystemCapture(
     "C:\\Windows\\System32\\ipconfig.exe", //Command Line 
     ".",          //CmdRunDir 
     ListStdOut,        //Return List of StdOut 
     ListStdErr,        //Return List of StdErr 
     RetCode         //Return Exit Code 
    ); 
    if (rc < 0) { 
     cout << "ERROR: SystemCapture\n"; 
    } 

    cout << "STDOUT:\n"; 
    cout << ListStdOut; 

    cout << "STDERR:\n"; 
    cout << ListStdErr; 

    cout << "Finished.\n"; 

    cout << "Press Enter to Continue"; 
    cin.ignore(); 

    return 0; 
} 

지금 당신이 이해 할 수 있습니다 여기에 나를 위해 일한 솔루션입니다.