Matlab Mex 파일에서 Cout을 대체하기 위해 StringBuf를 올바르게로드
-
04-07-2019 - |
문제
Mathworks는 현재 사용할 수 없습니다 cout
MATLAB 데스크탑이 Stdout을 방향식으로 열렸을 때 MEX 파일에서. 현재의 해결 방법은 기능을 제공하고 있으며 Mexprintf, 대신 사용을 요청합니다. 조금씩 인터넷 검색을 한 후에는 연장 할 수 있다고 생각합니다. std::stringbuf
내가 필요한 것을 할 수있는 수업. 지금까지 내가 가진 것이 있습니다. 이것은 충분히 강력합니까, 아니면 과부하에 필요한 다른 방법이 있습니까? 아니면 더 나은 방법이 있습니까? (일반적인 유닉스 환경에서 휴대 성과 사용 능력을 찾고 std::cout
이 코드가 MEX 실행 파일에 연결되어 있지 않으면 정상적으로)
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());
해결책
당신은 정말로 과부하를 원하지 않습니다 std::stringbuf
, 당신은 과부하를 원합니다 std::streambuf
또는 std::basic_streambuf
(여러 문자 유형을 지원하려면) 오버 플로우 방법도 무시해야합니다.
그러나 나는 또한 당신의 문제에 대한 해결책을 다시 생각해야한다고 생각합니다.
cout
그냥 an입니다 ostream
, 모든 클래스 / 기능이 사용하는 경우 ostream
그런 다음 좋아하는 모든 것을 통과 할 수 있습니다. 예를 들어 cout
, ofstream
, 등
그것이 너무 힘들다면 나는 내 자신의 버전을 만들 것입니다. cout
, 아마도 전화 할 수도 있습니다 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;
런타임 버전은 조금 더 작동하지만 쉽게 가능합니다.
다른 팁
셰인, 도와 주셔서 대단히 감사합니다. 마지막 작업 구현은 다음과 같습니다.
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);
...
// Restore the std stream buffer
std::cout.rdbuf(outbuf);
OP의 최종 구현을 약간 변경하여 생성자와 소멸자를 추가했습니다. 이 클래스의 객체 생성은 스트림 버퍼를 자동으로 대체합니다. std::cout
, 그리고 객체가 범위를 벗어나면 원래 스트림 버퍼가 복원됩니다. raii!
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 파일에서 스트림 버퍼를 사용하려면 간단히 말합니다.
mxstreambuf mout;
std::cout << "Hello World!\n";
... 그리고 아무것도 잊어 버리는 것에 대해 걱정하지 마십시오.