Ich arbeite daran, eine C ++ - API zu verpacken, die den Zugriff auf einen Datenspeicher (Hazelcast) in C-Funktionen ermöglicht, damit auf den Datenspeicher auch über C-only-Code zugegriffen werden kann.
Die Hazelcast C ++ - API für die Map-Datenstruktur sieht folgendermaßen aus:
auto map = hazelcastClient->client->getMap<int, string>(mapName);
map.put(key, value);
Es werden Vorlagentypen keyund valueParameter verwendet. Da in C keine Vorlagen verfügbar sind, habe ich mir überlegt, für jede Spezialisierung der getMap<T, U>Methode eine Wrapper-Funktion zu erstellen . Das heißt, für jeden C-Typ. Obwohl ich bin mir bewusst , dass es signedund unsignedVersionen von C - Typen, ich bin gut mit der API - Begrenzung nur zu unterstützen int, double, float, char *für keyund value.
Also habe ich ein kleines Skript geschrieben, das alle Kombinationen automatisch generiert. Die exportierten Funktionen sehen folgendermaßen aus:
int Hazelcast_Map_put_int_string(
Hazelcast_Client_t *hazelcastClient,
const char *mapName,
int key,
char *value,
char** errptr
);
int Hazelcast_Map_put_int_int(
Hazelcast_Client_t *hazelcastClient,
const char *mapName,
int key,
int value,
char** errptr
);
...
Erzeugen eine Funktion für get, set, containsmit allen möglichen Kombinationen von keyund valueArten erhöht die Menge an Code ziemlich viel, und obwohl ich den Code denke Erzeugung eine gute Idee ist, fügt es zusätzliche Komplexität , indem er eine Art von Code-generierenden Infrastruktur zu schaffen.
Eine andere Idee, die ich mir vorstellen kann, ist eine generische Funktion in C wie diese:
int Hazelcast_Map_put(
Hazelcast_Client_t *hazelcastClient,
const char *mapName,
const void *key,
API_TYPE key_type,
const void *value,
API_TYPE value_type,
char** errptr
);
Welches kann so verwendet werden:
Hazelcast_Map_put(client, mapName, "key", API_TYPE_STR, "val", API_TYPE_STR, &err);
Dies macht es für den Anrufer etwas einfacher, da es die Last der korrekten Spezialisierung auf meinen Code verlagert, aber die Typensicherheit verliert und Casts erfordert. Außerdem würde für die Übergabe eines Int, wie void *es jetzt der Typ von keyund ist value, eine Besetzung wie (void *) (intptr_t) intValauf der Anruferseite benötigt, was wiederum nicht besonders schön zu lesen und zu pflegen ist.
- Gibt es eine dritte Option, die ich nicht erkennen kann?
- Welche Version würden C-Entwickler bevorzugen?
Ich bin meistens geneigt, alle Typkombinationen automatisch zu generieren und für jede eine Funktion zu erstellen, obwohl die Header-Datei vermutlich ziemlich groß wird.