Umschreiben eines Programms von C auf C++

_Grubi

Erfahrenes Mitglied
Guten Abend,


ich habe mir vor einer Weile für ein Programm das Modul-System von Apache angeschaut und das auch so größtenteils für mich übernommen. Das Ganze wurde damals in C gebastelt. Mittlerweile bin ich aber auf C++ umgestiegen und wollte das Projekt dahingehend aktualisieren.

Nun hänge ich aber an einer Stelle und kann mir nicht erklären, warum: Ich bekomme einen Kompilerfehler.
Hier mal die Stelle, die mir Probleme macht:

Um Befehle zu Registrieren habe ich folgenden Aufruf:
C++:
static const command_rec loader_cmds[] = {
	INIT_TAKE2("LoadModule", load_module, "Syntax: LoadModule NAME_module PATH/mod_NAME.so"),
    {NULL}
};

INIT_TAKE2 ist folgendermaßen definiert:
C++:
# define INIT_TAKE2(directive, func_, errmsg) \
    { directive, { .take2=func_ }, TYPE_TAKE2, errmsg }

Und damit command_rec auch noch bekannt ist, hier der Rest
C++:
enum cmd_how {
    TYPE_TAKE1,			/**< one argument only */
    TYPE_TAKE2,			/**< two arguments only */
    TYPE_FLAG			/**< One of 'On' or 'Off' */
};

typedef union {
    /** function to call for a take1 */
    const char *(*take1) (const char *w);
    /** function to call for a take2 */
    const char *(*take2) (const char *w, const char *w2);
    /** function to call for a flag */
    const char *(*flag) (int on);
} cmd_func;

typedef struct command_struct command_rec; 
struct command_struct {
    /** Name of this command */
    const char *name;
	
	/** The function to be called when this directive is parsed */
    cmd_func func;
	enum cmd_how func_type;
		
    /** 'usage' message, in case of syntax errors */
    const char *errmsg;
};

Nun bekomme ich vom Kompiler folgende Meldung an den Kopf geworfen:
g++ hat gesagt.:
Loader.cpp:59: error: expected primary-expression before '.' token

Da ich nicht weiß, wonach ich für diesen Fall speziell suchen muss, kann ich es leider auch nicht selbst lösen.

Zur kurzen Erklärung, was da genau geschieht:
Mit INIT_TAKE2 soll eine Funktion an einen Befehl gebunden werden, welche 2 Parameter annehmen kann. Dazu wird dann func_type auf TYPE_TAKE2 gesetzt und via {.type2=func_} soll bei func die Funktion auf type2 gelegt werden.

Ich bin eigentlich davon ausgegangen, dass C++ auch das kann, was C kann. Ich könnte es natürlich auch anders lösen, aber zum Verständnis würde mich dennoch mal Interessieren, warum das nicht mehr geht.

Danke schonmal für die einleuchtenden Erklärungen :p

Gruß,
grubi
 
Hi.

Man kann keine Strukturen in C++ mittels benannten Mitgliedern initialisieren (das geht nur in C99):
C++:
struct X { char* name, int age };

X x = { .age = 22 }; // invalid C++
Gruß

PS: das Gleiche gilt natürlich auch für unions.
 
Zuletzt bearbeitet:
Danke für kleine Erklärung.

Gibt es eine gute Alternative dafür? Denn dieser Weg hatte den Vorteil, dass man den Rest nicht imemr anpassen müsste, wenn man einen Funktionstyp (sprich mehr parameter oder Ähnliches) hinzufügt.

Oder bleibt mir wirklich nur die Möglichkeit auf cmd_func zu verzichten und die Funktionstypen direkt in command_struct aufzunehmen (was dann jedes Mal angepasst werden müsste.)

Gruß
 
Hi.

Füge einfach als erstes Mitglied in die union einen Zeiger auf void ein.

C++:
# define INIT_TAKE2(directive, func_, errmsg) \
    { directive, { reinterpret_cast<void*>(func_) }, TYPE_TAKE2, errmsg }

Oder gleich die Holzhammermethode:
C++:
# define INIT_TAKE2(directive, func_, errmsg) \
    { directive, { reinterpret_cast<const char* (*) (const char*)>(func_) }, TYPE_TAKE2, errmsg }
Gruß
 
Zuletzt bearbeitet:
Werde ich morgen ausprobieren. Ich bin immer davon ausgegangen, dass bei Zeigern zu Funktionen immer die Anzahl der Parameter bekannt sein muss.
 
Funktioniert wunderbar, danke dir :)

Nur eine Änderung musste ich machen: die geschweiften Klammern um reinterpret_cast muss man wohl weglassen.
 
Zurück