Domanda

Attualmente MathWorks non ti consente di utilizzare cout da un file mex quando il desktop MATLAB è aperto perché hanno reindirizzato stdout. La loro soluzione alternativa attuale sta fornendo una funzione, mexPrintf, che ti richiedono invece di utilizzare . Dopo aver cercato su Google un po ', penso che sia possibile estendere la classe std :: stringbuf per fare ciò di cui ho bisogno. Ecco cosa ho finora. È abbastanza robusto o ci sono altri metodi che devo sovraccaricare o un modo migliore per farlo? (Alla ricerca della portabilità in un ambiente UNIX generale e della possibilità di utilizzare std :: cout normalmente se questo codice non è collegato a un eseguibile 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());    
È stato utile?

Soluzione

Non vuoi davvero sovraccaricare std :: stringbuf , vuoi sovraccaricare std :: streambuf o std :: basic_streambuf (se desideri supportare più tipi di caratteri), devi anche sovrascrivere il metodo di overflow.

Ma penso anche che tu debba ripensare la tua soluzione al tuo problema.

cout è solo un ostream , quindi se tutte le classi / funzioni accettano un ostream , puoi passare qualsiasi cosa tu voglia. per esempio. cout , ofstream , ecc.

Se è troppo difficile, creerei la mia versione di cout , forse chiamata mycout che può essere definita in fase di compilazione o di runtime (a seconda di ciò che voglio fare).

Una soluzione semplice può essere:

#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;

E la versione cout potrebbe essere:

typedef std::cout mycout;

Una versione di runtime è un po 'più di lavoro ma facilmente realizzabile.

Altri suggerimenti

Shane, grazie mille per il tuo aiuto. Ecco la mia implementazione di lavoro finale.

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); 

Ho modificato un po 'l'implementazione finale dell'OP, aggiungendo un costruttore e un distruttore. La creazione di un oggetto di questa classe sostituisce automaticamente il buffer di flusso in std :: cout e quando l'oggetto esce dall'ambito, viene ripristinato il buffer di flusso originale. 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;
};

Per utilizzare il buffer di flusso in un file MEX, semplicemente:

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

... e non preoccuparti di dimenticare nulla.

cout è un flusso di output di caratteri particolare. Se si desidera un cout che scrive in un file, utilizzare un < code> fstream , in particolare un ofstream . Hanno la stessa interfaccia fornita da cout . Inoltre, se vuoi prendere il loro buffer (con rdbuf ) puoi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top