Pregunta

MathWorks actualmente no le permite usar cout de un archivo mex cuando el escritorio de MATLAB está abierto porque han redirigido la salida estándar. Su solución actual es proporcionar una función, mexPrintf, que le piden que use en su lugar . Después de buscar en Google un poco, creo que es posible extender la clase std :: stringbuf para hacer lo que necesito. Esto es lo que tengo hasta ahora. ¿Es lo suficientemente robusto o hay otros métodos que necesito para sobrecargar o una mejor manera de hacerlo? (Buscando la portabilidad en un entorno general de UNIX y la capacidad de usar std :: cout de la forma habitual si este código no está vinculado a un ejecutable 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());    
¿Fue útil?

Solución

Realmente no desea sobrecargar std :: stringbuf , quiere sobrecargar std :: streambuf o std :: basic_streambuf (Si desea admitir varios tipos de caracteres), también debe anular el método de desbordamiento también.

Pero también creo que necesitas repensar tu solución a tu problema.

cout es solo un ostream , por lo que si todas las clases / funciones toman un ostream , entonces puede pasar lo que quiera. p.ej. cout , ofstream , etc

Si eso es demasiado difícil, crearía mi propia versión de cout , tal vez llamada mycout que se puede definir en tiempo de compilación o en tiempo de ejecución (dependiendo de lo que quiero hacer).

Una solución simple puede ser:

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

Y la versión cout podría ser:

typedef std::cout mycout;

Una versión en tiempo de ejecución es un poco más de trabajo, pero es fácil de hacer.

Otros consejos

Shane, muchas gracias por tu ayuda. Aquí está mi implementación final de trabajo.

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

He cambiado un poco la implementación final del OP, agregando un constructor y un destructor. La creación de un objeto de esta clase reemplaza automáticamente el búfer de flujo en std :: cout , y cuando el objeto se sale del alcance, el búfer de flujo original se restaura. 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;
};

Para usar el búfer de flujo en un archivo MEX, simplemente:

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

... y no te preocupes por olvidar nada.

cout es un flujo de salida de caracteres particular. Si desea un cout que escribe en un archivo, use un < código> fstream , particularmente un ofstream . Tienen la misma interfaz que cout proporciona. Además, si desea capturar su búfer (con rdbuf ) puede hacerlo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top