C++ 正确加载stringbuf以替换MATLAB mex文件中的cout

C++ 正确加载stringbuf以替换MATLAB mex文件中的cout,c++,matlab,cout,mex,stringbuffer,C++,Matlab,Cout,Mex,Stringbuffer,MathWorks当前不允许您在打开MATLAB桌面时使用mex文件中的cout,因为它们已重定向stdout。他们当前的解决方法是提供一个函数。在谷歌搜索了一下之后,我认为可以扩展std::stringbuf类来做我需要的事情。这是我到目前为止所拥有的。这是否足够健壮,或者是否有其他方法需要重载,或者有更好的方法来实现这一点?(寻找通用UNIX环境中的可移植性,以及在该代码未与mex可执行文件链接的情况下正常使用std::cout的能力) class-mstream:public-string

MathWorks当前不允许您在打开MATLAB桌面时使用mex文件中的
cout
,因为它们已重定向stdout。他们当前的解决方法是提供一个函数。在谷歌搜索了一下之后,我认为可以扩展
std::stringbuf
类来做我需要的事情。这是我到目前为止所拥有的。这是否足够健壮,或者是否有其他方法需要重载,或者有更好的方法来实现这一点?(寻找通用UNIX环境中的可移植性,以及在该代码未与mex可执行文件链接的情况下正常使用
std::cout
的能力)

class-mstream:public-stringbuf{
公众:
虚拟流大小xsputn(常量字符*s,标准::流大小n)
{
mexPrintf(“*s”,s,n);
返回基本流buf::xsputn(s,n);
}
}; 
mstream-mout;
exputf=cout.rdbuf(mout.rdbuf());

cout
是一个特定的字符输出流。如果需要写入文件的
cout
,请使用,尤其是。它们具有与
cout
提供的相同的接口。此外,如果您想获取它们的缓冲区(使用
rdbuf
),您可以。

如果您真的不想重载
std::stringbuf
,您想重载
std::streambuf
std::basic_streambuf
(如果您想支持多种字符类型),还需要重写溢出方法

但我也认为你需要重新思考你的问题解决方案

cout
只是一个
ostream
,因此如果所有类/函数都采用
ostream
,那么您可以传入任何您喜欢的内容。e、 g.
cout
、流的

如果这太难,那么我将创建自己的
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;

运行时版本需要更多的工作,但很容易实现。

Shane,非常感谢您的帮助。这是我最后的工作实现

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


我稍微改变了OP的最终实现,添加了构造函数和析构函数。创建此类的对象会自动替换
std::cout
中的流缓冲区,当对象超出范围时,会恢复原始流缓冲区。雷伊

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";
mxstreambuf mout;

恢复std流缓冲区被证明是非常重要的。如果不这样做,我的mex函数似乎会出现某种内存问题,并在重新编译时使matlab崩溃。
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); 
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;
};
mxstreambuf mout;
std::cout << "Hello World!\n";