8

cout現在、MathWorksでは、MATLABデスクトップが開いているときにmexファイルから使用することはできません。これは、stdoutがリダイレクトされているためです。現在の回避策は、代わりに使用するように要求する関数mexPrintfを提供することです。少し調べてみると、std::stringbufクラスを拡張して必要なことをすることができると思います。これが私がこれまでに持っているものです。これは十分に堅牢ですか、それともオーバーロードする必要がある他の方法やこれを行うためのより良い方法がありますか?std::cout(一般的なUNIX環境での移植性と、このコードが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());    
4

4 に答える 4

9

シェーン、助けてくれてありがとう。これが私の最終的な実装です。

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); 
于 2008-10-30T01:28:13.467 に答える
9

をオーバーロードしたくない、オーバーロードしstd::stringbufたい、std::streambufまたはstd::basic_streambuf(複数の文字型をサポートしたい場合)、overflow メソッドもオーバーライドする必要があります。

しかし、問題に対する解決策を再考する必要があるとも思います。

coutは単なる である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;

ランタイム バージョンはもう少し手間がかかりますが、簡単に実行できます。

于 2008-10-28T19:46:45.123 に答える
1

コンストラクタとデストラクタを追加して、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";

...そして、何も忘れる心配はありません。

于 2016-12-22T05:42:26.110 に答える
0

cout特定の文字出力ストリームです。coutファイルに書き込む が必要な場合は、 fstream、特にofstream. が提供する同じインターフェイスを備えていcoutます。さらに、( を使用して) バッファーを取得したい場合rdbufは可能です。

于 2008-10-28T18:19:11.370 に答える