Frage

MathWorks ist zur Zeit nicht zulassen, dass Sie cout von einer mex-Datei verwenden, wenn die MATLAB-Desktop geöffnet ist, weil sie stdout umgeleitet haben. Ihre aktuelle Problemumgehung bietet eine Funktion, mexPrintf, dass sie fordern Sie stattdessen verwenden . um ein bisschen nach googeln, denke ich, dass es möglich ist, die std::stringbuf Klasse zu erweitern zu tun, was ich brauche. Hier ist, was ich bisher haben. Ist das robust genug ist, oder gibt es andere Methoden, die ich brauche, um eine Überlastung oder ein besserer Weg, dies zu tun? (Suche nach Portabilität in einer allgemeinen UNIX-Umgebung und die Fähigkeit std::cout als normal zu verwenden, wenn dieser Code nicht gegen einen mex ausführbaren verknüpft ist)

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());    
War es hilfreich?

Lösung

Sie wollen nicht wirklich std::stringbuf zu überlasten, wollen Sie std::streambuf oder std::basic_streambuf zu überlasten (falls Sie mehrere Zeichentypen unterstützen wollen), auch müssen Sie auch die Überlauf-Methode überschreiben.

Aber ich denke auch Sie Ihre Lösung für Ihr Problem zu überdenken müssen.

cout ist nur ein ostream, also wenn alle Klassen / Funktionen ein ostream nimmt, dann können Sie in alles, was Sie gerne weitergeben. z.B. cout, ofstream, etc

Wenn das zu hart ist, dann würde ich meine eigene Version von cout schaffen, vielleicht genannt mycout, die an jedem Compiler oder Laufzeit Zeit definiert werden kann (je nachdem, was Sie tun wollen).

Eine einfache Lösung kann sein:

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

Und die cout Version konnte nur sein:

typedef std::cout mycout;

Eine Runtime-Version ist ein bisschen mehr Arbeit, aber leicht machbar.

Andere Tipps

Shane, vielen Dank für Ihre Hilfe. Hier ist meine letzte Arbeits Umsetzung.

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

Ich habe die OP der endgültige Umsetzung ein wenig verändert, einen Konstruktor und Destruktor hinzufügen. ein Objekt dieser Klasse erstellen ersetzt automatisch den Strompuffer in std::cout, und wenn das Objekt den Bereich verlässt, wird der ursprüngliche Strompuffer wiederhergestellt. RAH!

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

Um den Strompuffer in einer MEX-Datei zu verwenden, einfach:

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

... und keine Sorge über alles zu vergessen.

cout ist ein bestimmtes Zeichen Ausgabestrom. Wenn Sie eine cout möchten, die in eine Datei schreibt, verwenden Sie einen fstream , insbesondere ein ofstream . Sie haben die gleiche Schnittstelle, die cout zur Verfügung stellt. Außerdem, wenn Sie wollen, dass ihre Puffer (mit rdbuf) greifen Sie können.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top