Question

MathWorks ne vous permet actuellement pas d'utiliser cout à partir d'un fichier mex lorsque le bureau MATLAB est ouvert car ils ont redirigé la sortie standard. Leur solution actuelle fournit une fonction, mexPrintf, qu'ils vous demandent d'utiliser à la place . Après avoir googlé un peu, je pense qu'il est possible d'étendre la classe std :: stringbuf pour faire ce dont j'ai besoin. Voici ce que j'ai jusqu'à présent. Est-ce assez robuste ou y a-t-il d'autres méthodes dont j'ai besoin pour surcharger ou une meilleure façon de le faire? (Vous recherchez une portabilité dans un environnement UNIX général et la possibilité d'utiliser std :: cout normalement si ce code n'est pas lié à un exécutable 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());    
Était-ce utile?

La solution

Vous ne voulez pas vraiment surcharger std :: stringbuf , vous voulez surcharger std :: streambuf ou std :: basic_streambuf (si vous souhaitez prendre en charge plusieurs types de caractères), vous devez également redéfinir la méthode de débordement.

Mais je pense aussi que vous devez repenser votre solution à votre problème.

cout est juste un ostream , donc si toutes les classes / fonctions prennent un ostream , vous pouvez alors passer tout ce que vous voulez. par exemple. cout , du courant , etc.

Si c'est trop difficile, je créerais ma propre version de cout , appelée peut-être mycout , qui peut être définie au moment du compilateur ou de l'exécution (selon ce que vous voulez). vouloir faire).

Une solution simple peut être:

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

Et la version du cout pourrait bien être:

typedef std::cout mycout;

Une version d'exécution représente un peu plus de travail mais est facilement réalisable.

Autres conseils

Shane, merci beaucoup pour votre aide. Voici ma dernière implémentation fonctionnelle.

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

J'ai légèrement modifié l'implémentation finale du PO en ajoutant un constructeur et un destructeur. La création d'un objet de cette classe remplace automatiquement le tampon de flux dans std :: cout et lorsque l'objet disparaît, le tampon de flux d'origine est restauré. 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;
};

Pour utiliser le tampon de flux dans un fichier MEX, simplement:

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

... et ne vous inquiétez pas pour rien oublier.

cout est un flux de sortie de caractère particulier. Si vous voulez un cout qui écrit dans un fichier, utilisez un < code> fstream , en particulier un ofstream . Ils ont la même interface que cout fournit. De plus, si vous voulez récupérer leur tampon (avec rdbuf ), vous pouvez.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top