صحيح الإفراط في تحميل stringbuf ليحل محل cout في ملف MEX MATLAB
-
04-07-2019 - |
سؤال
وماثووركس حاليا لا يسمح لك باستخدام cout
من ملف مكس عند سطح المكتب MATLAB مفتوح لأنهم إعادة توجيه المعياري. الحل ضعها الراهن هو توفير وظيفة، mexPrintf، التي يطلبونها كنت تستخدم بدلا من ذلك . بعد غوغلينغ حول قليلا، وأعتقد أنه من الممكن تمديد الطبقة std::stringbuf
أن تفعل ما أحتاج. وهنا ما لدي حتى الآن. هذا هو قوي بما فيه الكفاية، أم أن هناك أساليب أخرى أحتاج الزائد أو طريقة أفضل للقيام بذلك؟ (أبحث عن قابلية في بيئة UNIX العامة والقدرة على استخدام std::cout
كالمعتاد إذا لم يتم ربط هذا الرمز ضد تنفيذ المكسيك)
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());
المحلول
وأنت لا تريد حقا أن الزائد std::stringbuf
، وتريد أن تفرط std::streambuf
أو std::basic_streambuf
(إذا كنت ترغب في دعم أنواع الحرف متعددة)، كما تحتاج إلى تجاوز أسلوب تجاوز أيضا.
ولكن أعتقد أيضا تحتاج إلى إعادة التفكير في حل لمشكلتك.
و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;
وهناك نسخة وقت التشغيل هو أكثر قليلا من العمل ولكن قابلة للتنفيذ بسهولة.
نصائح أخرى
وشين، شكرا جزيلا لمساعدتكم. وهنا قال لي تنفيذ العمل النهائي.
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);
ولقد تغيرت التنفيذ النهائي للOP في قليلا، مضيفا منشئ والمدمر. إنشاء كائن من هذه الفئة تلقائيا يستبدل عازلة تيار في std::cout
، وعندما ينتقل الكائن خارج النطاق، يتم استعادة المخزن المؤقت التيار الأصلي. 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;
};
لاستخدام المخزن المؤقت تيار في ملف MEX، ببساطة:
mxstreambuf mout;
std::cout << "Hello World!\n";
... ولا تقلق بشأن نسيان أي شيء.