Referenzierung von Funktionen über Pointer
-
pumuckl schrieb:
param.pfn ist der Funktionspointer, den musst du dereferenzieren:
(*(param.pfn))(12345);Das hatte ich als allererstes versucht. Doch auch da gibt es eine, wenn auch andere, Fehlermeldung.
error C2064: term does not evaluate to a function taking 2 arguments
In der Hilfe zu C2064 kömmt:
A call is made to a function through an expression. The expression does not evaluate to a function pointer.
hier mal mein originalcode:
class xjhView; class CxjhStream { public: CxjhStream( void); CxjhStream( void (CxjhView::*pfn)( const char *s, int i), int color); ~CxjhStream( void); CxjhStream& operator<< (CxjhStream& ( *pf )(CxjhStream& out)); void (CxjhView::* pfn)( const char *s, int i); void putstr( const char *s); }; CxjhStream& operator<< (CxjhStream &out, const char *s) { ((out.*pfn))( s, out.color); // pfn undeclared (*(out.pfn))( s, color); // C2171: '*' : illegal on operands of type 'void (__thiscall CxjhView::* )(const char *,int) out.putstr( s); // als workaround, führt zu oben genanntem C2064 return out; } void CxjhStream::putstr( const char *s) { (this->pfn)( s, color); // C2064 pfn( s, color); // C2064 (*pfn)( s, color); // C2171 '*' illegal on operands of type 'void __thiscall CxjhView::* )(const char *,int)' }MQ
-
Um deinen Methodenpointer dereferenzieren zu können brauchst Du ein passendes (in deinem Fall
xjhView) Objekt dazu. BTW: DervoidParameter von des c-tors ist unnötig und der des d-tors sogar ungültig.greetz, Swordfish
PS:
typedefist was Tolles...
-
Das kann so nicht gehen

CxjhStream& operator<< (CxjhStream &out, const char *s)hier hast du vergessen anzugeben, dass der Operator ein Element der Klasse CxjhStream ist. Bzw. noch einen anderen Fehler gemacht.
class my_stream { typedef void (my_stream::*fnPtr)(const char*, int); fnPtr m_function; int m_color; public: my_stream(fnPtr function(NULL), const int color(0)) : m_function(function), m_color(color) {} friend my_stream& operator<< (my_stream& out, const char* string) { (out.*out.m_function)(string, out.m_color); return out; } };so sollte es gehen. Evtl. aber auch:
{ (out.*(out.m_function))(string, out.m_color); return out; }...
-
(D)Evil, ich möcht' Dir nicht den Spaß verderben, aber sein Methodenpointer ist vom Typ
CxjhView::*.greetz, Swordfish
-
Na dann hat er halt NOCH EINEN Fehler drin. Memberfunktionen können nur per entsprechendem Objekt aufgerufen werden!
-
(D)Evil schrieb:
Na dann hat er halt NOCH EINEN Fehler drin. Memberfunktionen können nur per entsprechendem Objekt aufgerufen werden!
und genau da kommt der Schlammassel ja her.
Das was ich hier vorgestellt habe, ist der Versuch einen Zirkelschluss zu brechen.
Das eigentliche Problem ist ein Henne-Ei Problem.
Ich habe eine Klasse, die die Bildschirmausgabe eines Fensters regelt, MFC CView. Weiterhin habe ich eine alte Konsolenanwendung, die auf iostream basiert und mit std::cout und std::cerr werkelt. Beides muss ich nun zusammenbringen.
Daher muss ich cout so nachbauen, dass der originale Code so wenig wie möglich verändert werden muss und mein neues cout die Ausgabe ins CView übergibt. Bei dem Versuch, die Routine von CView in meinem Stream aufzurufen, habe ich mich verheddert, weil mein Stream CView kennen muss und umgekehrt. Irgendwie ließ sich das nicht auflösen. Also ging ich soweit zu versuchen, einfach einen Pointer auf die entsprechende Funktion (Member von View) im Stream zu hinterlegen und diese dann aufzurufen.
Aber auch das wird nicht gehen, weil sich das irgendwie alles selbst hinten reinbeißt.
MQ
-
Mach es dir einfacher: Streambuffer ableiten, der die Ausgabe in CView umleitet. Dann einfach dein std::cout, std::clog und std::cerr auf den Streambuffer umleiten und fertig

-
(D)Evil schrieb:
Mach es dir einfacher: Streambuffer ableiten, der die Ausgabe in CView umleitet. Dann einfach dein std::cout, std::clog und std::cerr auf den Streambuffer umleiten und fertig

Sorry, bin kein Profi!
Was meinst du mit Streambuffer, den rdbuf()?
Wie leite ich std::cerr um??
Die CView-Klasse bzw. genauer die CRichEditCtrl bietet streaming in den internen Buffer an. Das habe ich ausprobiert, scheitert aber leider daran, dass damit immer nur der komplette Buffer angesprochen wird. Rufe ich die Streamin-Routine ein zweites mal auf, wird der Inhalt vom ersten mal gelöscht. Ich kann nix anhängen sondern nur komplett den Inhalt ersetzen.
MQ
-
Also in C++ haben Streams, die von std::ios abgeleitet sind, einen Buffer(std::basic_streambuf).
Wenn du nun einen eigenen streambuf von std::streambuf ableitest, und setzt dann den Buffer:my_streambuf buffer; std::cout.rdbuf(&buffer); std::clog.rdbuf(&buffer); std::cerr.rdbuf(&buffer);ein Beispiel, wie du von std::streambuf ableitest, findest du als "Weiche" hier im Forum.
-
(D)Evil schrieb:
Also in C++ haben Streams, die von std::ios abgeleitet sind, einen Buffer(std::basic_streambuf).
Wenn du nun einen eigenen streambuf von std::streambuf ableitest, und setzt dann den Buffer:my_streambuf buffer; std::cout.rdbuf(&buffer); std::clog.rdbuf(&buffer); std::cerr.rdbuf(&buffer);ein Beispiel, wie du von std::streambuf ableitest, findest du als "Weiche" hier im Forum.
Funktioniert das?? In meinem Fall jedenfalls nicht so wie gewünscht!
Von einem Konsolenprogramm werden normalerweise mehrere und verschiedene Aufrufe von cout getätigt. Nach einem flush() landet der Inhalt von Streampuffer auf dem Bildschirm. Danach ist der Streampuffer wieder leer, der ehemalige Inhalt aber bleibt auf dem Screen erhalten.
Das einfache "Umbiegen" des Streampuffers auf einen eigenen oder den einer CView-Klasse bringt nicht das gewünschte Ergebnis. Wie schon erwähnt, wird nach einem flush() der Puffer geleert. Nach einem Neuaufbau des Bildschirms wäre dann auch der alte Inhalt weg.
Was ich brauche ist ein Stream, der den Inhalt seines Puffers an den Inhalt der CView hintanhängt. Nun habe ich keinen direkten Zugriff auf den Puffer/Speicher von CView bzw. CRichEditView und kann nur über Memberfunktions Inhalte einfügen.
Bei dem Versuch, meiner Streamklasse Zugriff auf die geschützen bzw. privaten Funktionen von CRichEditView zu ermöglichen habe ich mich verheddert. Ein "Schlupfloch" konnte ich nicht finden.
Den erwähnten Zirkelschluss konnte ich inzwischen brechen. Ich muss nur meinem Stream nicht CView mitgeben sondern die Tochterklasse, die den Inhalt verwaltet, nämlich CRichEditCtrl.
Damit muss CView meinen Stream kennen und mein Stream eben nicht CView sondern CRichEditCtrl. Damit komm ich hin.
Die Abhängigkeiten der MFC sind derart verworren und vielschichtig, dass ich es als "Hobbyprogrammierer" nicht hinbekommen hatte, alle Abhängigkeiten zufrieden zu stellen. Und dann fängt man an zu probieren und zu basteln und verschlimmbessert alles. Na ja, jetzt tutet es.MQ