2008-10-28 9 views
8

MathWorks는 현재 stdout이 재 지정 되었기 때문에 MATLAB 데스크톱이 열려있을 때 mex 파일에서 cout을 사용할 수 없습니다. 현재 해결 방법은 함수 mexPrintf, that they request you use instead을 제공하는 것입니다. 인터넷 검색을 조금 해본 후, 필자는 필요한 작업을 수행하기 위해 std :: stringbuf 클래스를 확장 할 수 있다고 생각합니다. 여기 내가 지금까지 가지고있는 것이있다. 이것은 충분히 견고합니까? 아니면 과부하가 필요한 다른 방법이 있습니까? 아니면이를 수행하는 더 좋은 방법이 있습니까?MATLAB mex 파일에서 cout을 대체하기 위해 stringbuf를 올바로 오버로드합니다.

class mstream : public stringbuf { 
public: 
    virtual streamsize xsputn(const char *s, std::streamsize n) 
    { 
mexPrintf("*s",s,n); 
return basic_streambuf<char, std::char_traits<char>>::xsputn(s,n); 
    } 
}; 

mstream mout; 
outbuf = cout.rdbuf(mout.rdbuf());  

답변

9

std :: stringbuf를 오버로드하고 싶지 않고 std :: streambuf 또는 std :: basic_streambuf를 오버로드하려면 (여러 문자 유형을 지원하려는 경우) 오버플로 메서드를 다음과 같이 재정의해야합니다. 잘.

하지만 문제에 대한 해결책을 재고해야한다고 생각합니다.

cout은 단지 ostream이므로 모든 클래스/함수가 ostream을 사용하면 원하는 모든 것을 전달할 수 있습니다. 예 : cout, ofstream 등

너무 힘들면 자신이 원하는 버전에 따라 컴파일 시간 또는 런타임에 정의 할 수있는 mycout이라는 자체 버전을 만들 수 있습니다.

#include <streambuf> 
#include <ostream> 

class mystream : public std::streambuf 
{ 
public: 
    mystream() {} 

protected: 
    virtual int_type overflow(int_type c) 
    { 
     if(c != EOF) 
     { 
      char z = c; 
      mexPrintf("%c",c); 
      return EOF; 
     } 
     return c; 
    } 

    virtual std::streamsize xsputn(const char* s, std::streamsize num) 
    { 
     mexPrintf("*s",s,n); 
     return num; 
    } 
}; 

class myostream : public std::ostream 
{ 
protected: 
    mystream buf; 

public: 
    myostream() : std::ostream(&buf) {} 
}; 

myostream mycout; 

을 그리고 COUT 버전은있을 수 :

간단한 해결책이 될 수있다

typedef std::cout mycout; 

런타임 버전은 좀 더 일하지만, 쉽게 행할 수있다.

0

cout는 특정 문자 출력 스트림 (일반적인 UNIX 환경에서 이동성이 코드가 MEX 실행 파일에 링크되어 있지 않은 경우 정상적으로 표준 : COUT를 사용할 수있는 능력을 찾고). 파일에 쓰는 cout을 사용하려면 fstream, 특히 ofstream을 사용하십시오. 그들은 cout과 동일한 인터페이스를 가지고 있습니다. 또한 버퍼를 잡으려면 (rdbuf) 할 수 있습니다.

9

쉐인, 도움 주셔서 대단히 감사합니다. 여기 내 마지막 작업 구현입니다. 를 추가 내가 OP의 최종 구현을 약간 변경 한

// Restore the std stream buffer 
std::cout.rdbuf(outbuf); 
+0

std 스트림 버퍼를 복원하는 것이 매우 중요합니다. 이렇게하지 않고도 내 mex 함수는 일종의 메모리 문제를 일으키고 다시 컴파일 할 때 matlab을 추락시킨 것처럼 보였다. –

1

class mstream : public std::streambuf { 
public: 
protected: 
    virtual std::streamsize xsputn(const char *s, std::streamsize n); 
    virtual int overflow(int c = EOF); 
}; 

...

std::streamsize 
mstream::xsputn(const char *s, std::streamsize n) 
{ 
    mexPrintf("%.*s",n,s); 
    return n; 
} 

int 
mstream::overflow(int c) 
{ 
    if (c != EOF) { 
     mexPrintf("%.1s",&c); 
    } 
    return 1; 
} 

...

// Replace the std stream with the 'matlab' stream 
// Put this in the beginning of the mex function 
mstream mout; 
std::streambuf *outbuf = std::cout.rdbuf(&mout); 

..., 생성자와 소멸자. 이 클래스의 객체를 만들면 스트림 버퍼가 자동으로 std::cout으로 바뀌고 객체가 범위를 벗어나면 원본 스트림 버퍼가 복원됩니다. RAII!

mxstreambuf mout; 
std::cout << "Hello World!\n"; 

을 ... 아무것도 잊지 대해 걱정하지 마십시오 :

class mxstreambuf : public std::streambuf { 
    public: 
     mxstreambuf() { 
     stdoutbuf = std::cout.rdbuf(this); 
     } 
     ~mxstreambuf() { 
     std::cout.rdbuf(stdoutbuf); 
     } 
    protected: 
     virtual std::streamsize xsputn(const char* s, std::streamsize n) override { 
     mexPrintf("%.*s", n, s); 
     return n; 
     } 
     virtual int overflow(int c = EOF) override { 
     if(c != EOF) { 
      mexPrintf("%.1s", & c); 
     } 
     return 1; 
     } 
    private: 
     std::streambuf *stdoutbuf; 
}; 

간단하게하는 MEX-파일 스트림 버퍼를 사용합니다.