Я працюю над упаковкою API C ++, який забезпечує доступ до сховища даних (Hazelcast) у функціях C, так що до сховища даних також можна отримати доступ з коду, що містить лише C.
API Hazelcast C ++ для структури даних Map виглядає приблизно так:
auto map = hazelcastClient->client->getMap<int, string>(mapName);
map.put(key, value);
Він використовує типи шаблонів для key
та value
параметрів. Оскільки в C немає шаблонів, я думав про створення функції обгортки для кожної спеціалізації getMap<T, U>
методу. Тобто для кожного типу С. Хоча я знаю , що є signed
і unsigned
варіанти типів C, я штраф з обмеженням API для підтримки тільки int
, double
, float
, char *
для key
і value
.
Тому я написав невеликий сценарій, який автоматично генерує всі комбінації. Експортовані функції виглядають приблизно так:
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
);
...
Створення функції для get
, set
, contains
з усіма можливими комбінаціями key
і value
типами збільшує кількість коди досить багато, і , хоча я думаю , що генерування коди є хорошою ідеєю, це докладає додаткову складність, маючи для створення якого - то код , що генерує інфраструктури.
Ще одна ідея, яку я можу собі уявити, - це одна загальна функція в С, як це:
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
);
Які можна використовувати так:
Hazelcast_Map_put(client, mapName, "key", API_TYPE_STR, "val", API_TYPE_STR, &err);
Це полегшує для абонента, оскільки він перекладає тягар отримання правильної спеціалізації на мій код, але він втрачає безпеку типу і вимагає кастингу. Крім того, для передачі в int, як void *
зараз є тип, key
а також value
потрібен акторський (void *) (intptr_t) intVal
склад на стороні абонентів, що знову не дуже приємно читати та підтримувати.
- Чи є якийсь третій варіант, який я не можу розпізнати?
- Якій версії віддадуть перевагу розробники C?
Я здебільшого схильний до автоматичного генерування всіх комбінацій типів та створення функції для кожного, хоча, мабуть, файл заголовка стане досить величезним.