funktionspointer einer nicht-statischen memberfunction nicht erlaubt?
-
Hallo,
ich habe ein Problem bei der Verheiratung meines objektorientierten Frontends mit der C-API im Backend meines Projekts.
Und zwar brauche ich einen Funktionspointer der dafür zuständig ist, einen Wert an die C-API zu übertragen. Dummerweise ist dieser Wert aber eine Instanzvariable und ihr getter nicht statisch, was zu Problemen führt.
Also mal ein Codebeispiel damit man versteht was ich meine:
Die C-API erwartet einen Funktionspointer auf eine Funktion die einen void* übernimmt und einen int zurückgibt, was als GetDatai_f getypedeft ist:
typedef int (* GetDatai_f)(void * inRefcon);und diesen muss man registrieren, quasi wie ein Callback, durch Aufruf von RegisterDataAccessor die wie folgt deklariert ist:
void* RegisterDataAccessor(const char * inDataName, GetDatai_f inReadInt);So, jetzt hat meine Klasse, wie es sich gehört für ihre Membervariablen getter:
class Data { public: void setupAPI(); int getValue(void*) { return m_value; } private: int m_value; }:Und jetzt kommt der casus knacksus:
void Data::setupAPI() { RegisterDataAcessor("value",getValue); }Was partout nicht funktionieren will:
error: argument of type 'int (Data::)(void*)' does not match 'int (*)(void*)'Ich kann rumcasten wie ich will, es geht nicht.
Oder wenn ich den Adressoperator davor mache
void Data::setupAPI() { RegisterDataAcessor("value",&getValue); }dann
error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say '&Data::setupAPI' error: cannot convert 'int (Data::*)(void*)' to 'int (*)(void*)'Also was tun? Ich muss an eine private membervariable ran und der getter ist mitnichten statisch, aber ich brauch einen pointer in der geforderten Form.
Ich bin hier echt am verzweifeln, denn dieses ganze void* C-geraffel ist mir als OO-Fuzzi nicht meine Welt...Gruß,
Phil
-
-
parashift.com schrieb:
How do I pass a pointer-to-member-function to a signal handler?
Don't.Klasse. So eine Antwort hatte ich befürchtet... Jetzt fang ich doch wieder an die RefCon-Pointer runterzucasten und auf den daraus hervorgehenden Objekten rumzumachen. Genau das, was ich vermeiden wollte.
Man könnte ja sowas Schönes wie Referenzen, Funktoren oder boost::Function nehmen, aber nein, es ist das Jahr 2008 (!) und die Version 2.0 dieser API wird releast und sie verwenden WIEDER diese void-pointer-Scheiße!!! Ich könnt kotzen!!
-
Ich verstehe deine Wut zwar, aber grundsätzlich ist das ja ein wenig ein anderes Konzept. Normale Funktionspointer und Memberfunktionspointer.
Memberfunktionspointer sind Objektgebunden und die normalen halt nicht. Da bringt auch wildes rumgecasten nichts. Das Konzept ist dasselbe und kann gar nicht funktionieren, wenn du es mischen willst. Die API möchte eine Funktion aufrufen und die kannst du ihr geben (halt eine statische Funktion). Und wenn du ein Objekt damit verbinden willst, dann musst du das halt selber machen. (über den Parameter).
-
Bei C-APIs gehts halt nicht anders. Wenigstens kannst du einen void-Pointer übergeben.
-
So jetzt geht's. "Dank" der Referenzmitführung mit dem void*...
Dieses Codestück müsste man echt mal sehen: mitten in Objektorientierung mit allen Finessen und Template-Spezialisierungen steht dann auf einmal so ein static_cast auf einen void*...
Bin ich froh, dass dieser Teil des Projektes closed-source ist und sich diese Scheiße niemand angucken muss. 
@drakon: wütend bin ich auf diese API, nicht auf den C++-Standard. Dass pointer-to-member-function fundamental anders sind als normale funktionspointer ist ja einzusehen und hat seinen Sinn... Ich hatte nur insgeheim gehofft es gäbe einen anderen workaround.